Быстрое создание (x)HTML элементов методами DOM.

Добавление новых элементов обычными методами DOM скучное занятие, которое может вызвать справедливое недовольство: для каждого элемента получаются очень многословные и многоэтажные конструкции. Если нужно сделать один-два элемента (например, DIV или P и т.п.) с текстом внутри, еще можно смириться с написанием большого количества практически одинаковых строк кода. Ведь, создание элемента, DOM-метод document.createElement() редко обходится без добавления этому элементу различных атрибутов. Размещение текста внутри элемента потребует вызвать еще и метод создания текстового узла document.createTextNode(), а также appendChild(). В-общем, с этим нельзя мириться, надо бороться, а как - будет показано далее на примере создания элемента DIV с текстом внутри двумя способами.

Обычный способ


function handle_button() {
    var parent = document.getElementById('myContainer');
    var newdiv = document.createElement('div');
    newdiv.className = 'myDivCSSClass';
    newdiv.id = 'myDivId';
    newdiv.style.width = '200px';
    newdiv.style.height = '250px';
    newdiv.style.background = '#3B9D00';
    newdiv.style.color = '#fff';
    var text = "текст текст текст текст текст текст текст текст";
    var textNode = document.createTextNode(text);
    newdiv.appendChild(textNode);
    parent.appendChild(newdiv);
}

В функции handle_button() переменная parent ссылается на элемент с id="myContainer", в котором будет размещен новый элемент. Затем создается совершенно обычный новый элемент DIV, добавляются ему обычные атрибуты id, class и style, а также устанавливаются их значения. После создается текстовый узел, присоединяется созданному элементу DIV и все это размещается в элементе с id="myContainer". Чтобы сделать 10 новых DIV придется изрядно потрудиться, т.к. возможно, потребуется разместить их в разных местах веб-страницы, т.е. присоединить к разным элементам. Не стоит забывать о том, что значение атрибута id внутри документа должно быть уникальным, да и значения остальных атрибутов у элементов могут отличаться.

Удобный способ создания новых элементов

Эта функция поможет создать новый элемент, добавить ему различные атрибуты, а также присоединить к нему текстовый узел. Обязательным является только аргумент name.


function elem(name, attrs, style, text) {
    var e = document.createElement(name);
    if (attrs) {
        for (key in attrs) {
            if (key == 'class') {
                e.className = attrs[key];
            } else if (key == 'id') {
                e.id = attrs[key];
            } else {
                e.setAttribute(key, attrs[key]);
            }
        }
    }
    if (style) {
        for (key in style) {
            e.style[key] = style[key];
        }
    }
    if (text) {
        e.appendChild(document.createTextNode(text));
    }
    return e;
}

В качестве примера вызова функции создадим такой же DIV, как в самом начале статьи, с теми же атрибутами:


function handle_button() {
    var parent = document.getElementById('myContainer');
    parent.appendChild(elem('div',
      {'class': 'myDivCSSClass', 'id': 'myDivId'},
      {'width': '200px', 'height': '250px', 'background': '#3B9D00', 'color': '#fff'}, 
      'текст текст текст текст текст текст текст текст'));
}

Пример создания нового элемента

Это
, в котором надо разместить новый элемент.

Сделать новый элемент!

XML Matters: Beyond the DOM



Много комментариев (26) к “Быстрое создание (x)HTML элементов методами DOM.”

  1. Maxim :

    Поищите функцию domEl — еще удобнее


  2. Elf :

    Любой программист (если он программист) давно должен был обзавестись собственной библиотечкой, автоматизирующей сии безобразия. Это ж закон – любой код, повторенный дважды, должен быть вынесен в функцию :-)


  3. zed_0xff :


    if (style) {
    for (key in style) {
    e.style[key] = style[key];
    }
    }

    а почему не:


    if (style) {
    e.style = style;
    }

    ?


  4. AKS :

    2zed_0xff
    Вы бы сначала посмотрели, что из этого получится, а уж потом бы писали…


  5. Vitaly Harisov :

    Я использую innerHTML, когда это возможно. Код намного короче и понятнее получается.


  6. Евгений ?ванов :

    а лучше вот так
    if (attrs) {
    for (key in attrs) e.setAttribute(key, attrs[key]);
    }
    и называть атрибуты сразу.


  7. Евгений ?ванов :

    Хотя вспомнил, что id и className нельзя по setAttribute ставить….


  8. Евгений ?ванов :

    Насчёт innerHTML соглашусь. ?м очень удобно пользоваться, благо поддерживают все браузеры. и Работает быстрее, чем createElement, особенно на таблицах.


  9. Андрейка :

    > Насчёт innerHTML соглашусь. ?м очень удобно пользоваться, благо поддерживают все браузеры. и Работает быстрее, чем createElement, особенно на таблицах.

    … и невалидный код туда проще запихнуть. ? потом отлаживать часами, ищя, почему же разъехалось тоже проще…

    Вообщем, innerHTML — зачастую зло.


  10. Баранов Андрей :

    As there is no public specification for this property, implementations differ widely. For example, when text is entered into a text input, IE will change the value attribute of the input’s innerHTML property but Gecko browsers do not.

    It should never be used to write parts of a table—W3C DOM methods should be used for that—though it can be used to write an entire table or the contents of a cell.

    http://developer.mozilla.org/en/docs/DOM:element.innerHTML

    …иными словами, innerHTML конечно можно использовать для создания примитивного статического контента, если не планируется в дальнейшем широкое применение к нему методов DOM.


  11. Баранов Андрей :

    Elf, по первому предложению: кто-то, возможно, еще только начинает обзаводиться собственной библиотечкой.
    По второму – неоспоримый факт! :)

    Кстати, в коде скрипта из источника (по ссылке в конце статьи, см. выше) были ошибки (автор уже их исправил, но это говорит о том, что даже копируя готовый код, надо работать не только руками, но и головой).


  12. Vitaly Harisov :

    > It should never be used to write parts of a table

    Конечно, never, MSIE не позволяет сделать это.

    > …иными словами, innerHTML конечно можно использовать для создания примитивного статического контента, если не планируется в дальнейшем широкое применение к нему методов DOM.

    Вывод не понятен. После добавления частей DOM’а через innerHTML получаем такой же DOM, как и при использовании createElement. А вот использовать innerHTML в AJAX намного проще, выплёвывай себе куски HTML с сервера и всё.


  13. Баранов Андрей :

    Vitaly Harisov – писал в спешке, теперь и сам уже не пойму о чем… :)


  14. codework :

    2Elf: Спорное утверждение, иногда лучше повторить код несколько раз, чем выносить его в функцию, например там где важно быстродействие, или когда этот код состоит из 2-3 строк. Хотя есть куча примеров где наоборот не надо выносить повторяющийся код в отдельную функцию.


  15. WingedFox :

    Предлагаю ещё один вариант (имхо – самый удобный) :
    http://forum.dklab.ru/js/advises/DocumentCreateelementext.html


  16. DROOPY :

    >… и невалидный код туда проще запихнуть. ? потом отлаживать >часами, ищя, почему же разъехалось тоже проще…

    >Вообщем, innerHTML — зачастую зло.
    Да никакое это не зло.
    А для отладки существует “Developer Toolbar” для IE и “?спектор DOM” для FireFox


  17. flash-vkv :

    вот вам код им все сказано

    var node = document.createElement("tr");
    node.innerHTML = '1 ';
    alert(node.innerHTML); // собшение: 1 


  18. flash-vkv :

    чтота странно блок code работает должно было вывести след
    var node = document.createElement(”tr”);
    node.innerHTML = ‘1 ’;
    alert(node.innerHTML); // собшение: 1 


  19. flash-vkv :

    так и не получилось вставить строчку
    node.innerHTML = .’..1.&.n.b.s.p.;..’.;.


  20. Alexander :

    простое человеческое спасибо.


  21. Дмитрий :

    Спасибо за информацию ))
    Правда не совсем до конца разобрался..


  22. Frog007 :

    А я использую библиотеку MochiKit. ? там есть возможность писать так:
    var newDiv = DIV({style:”border:solid 1px black”}, [childNode]);

    а потом можно добавлять этот элемент в DOM.


  23. Яшин Дмитрий :

    Статья про оптимизацию яваскрипта при добавлении элементов DOM в документ. Читать всем! http://kpumuk.info/javascript/javascript-optimization-part-1-adding-dom-elements-to-document/lang/ru/


  24. Desc :

    А как сделать чтобы добавлялось новые сверху?


  25. Баранов Андрей :

    parent.insertBefore(new, any);

    parent – родительский контейнер
    new – новый элемент
    any – тот, перед которым надо вставить(внутри родительского)


  26. Алексей :

    столкнулся с проблемой
    если в text присутствуют хтмл-тэги, то они не работают :(
    отображаются как обычный текст
    кто подскажет как исправить?