У меня такой код:

tr = document.createElement("tr");
root.appendChild(tr);
td = document.createElement("td");
td.appendChild(document.createTextNode("some value"));
tr.appendChild(td);

Ну, этот код такой же, как

root.innerHTML = "<tr><td>some value</td></tr>";

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

4
yilmazhuseyin 10 Авг 2010 в 10:30

9 ответов

Лучший ответ

Вы всегда можете написать функции-оболочки вокруг неуклюжего DOM API, чтобы сделать код более читабельным. Я обычно использую что-то вроде:

function newElement (type,attr,children) {
    var el = document.createElement(type);
    for (var n in attr) {
        if (n == 'style') {
            setStyle(el,attr[n]); /* implementation of this function
                                   * left as exercise for the reader
                                   */
        }
        else {
            el[n] = attr[n];
        }
    }
    if (children) {
        for (var i=0; i<children.length; i++) {
            el.appendChild(children[i]);
        }
    }
}
function newText (text) {
    document.createTextNode(text);
}

Тогда вы можете написать гораздо более декларативный код:

var tr = newElement('tr',{},[
    newElement('td',{},[
        newText('some value')
    ])
]);

Просто запомните разницу между CSS и JavaScript:

var div = newElement('div',{
    className:'foo',
    style:{
        marginLeft:'10px'
    }
},[
    newText('notice we use "className" instead of class" '+
            'and "marginLeft" instead of "margin-left"')
]);
5
slebetman 10 Авг 2010 в 07:01

Используйте jQuery http://jquery.com/

$('#root tbody').append('<td><td>some value</td></td>');

Он даже будет использовать правильные методы DOM.

РЕДАКТИРОВАТЬ: из документов jQuery:

jQuery - это быстрая и краткая библиотека JavaScript, которая упрощает перемещение по HTML-документу, обработку событий, анимацию и взаимодействие с Ajax для быстрой веб-разработки. jQuery разработан, чтобы изменить способ написания JavaScript.

** РЕДАКТИРОВАТЬ: ** Кроме того, я сделал приведенный выше пример немного более совместимым с HTML @koby;)

0
Matt Williamson 10 Авг 2010 в 17:07

Вы пытались использовать шаблонизатор JavaScript?

Как правило, они вводят HTML-строки с помощью innerHTML и работают намного быстрее, чем манипуляции с DOM на настольных и мобильных устройствах, сохраняя при этом разделение между представлением и логикой.

Мы используем PURE, который полностью разделяет разметку HTML и логику JavaScript. Дизайнеры и разработчики могут работать вместе над одними и теми же источниками.

Если вам не нравится это, вы можете найти множество других в Интернете, которые могут лучше соответствовать вашему вкусу.

0
Peter Mortensen 29 Авг 2010 в 11:44

Я сам написал несколько тестов, которые сравнивают innerHTML и DOM API. DOM API был определенно быстрее.

Вот результаты (я проверял на Firefix 3.6.8 и Chrome 5.0.375.125 beta): http://yilmazhuseyindevelopment.appspot.com/ois/images/ahh5aWxtYXpodXNleWluZGV2ZWxvcG1lbnRyEQsSCUltYWdlRGF0YRiptwUM

В первом тесте я добавлял один текстовый узел в тело страницы 1000 раз с помощью DOM API и innerHTML.

Во втором тесте я создал таблицу с DOM API и внутренним HTML. Вот фактический код для моего теста:

<html>
    <head>
        <script type="text/javascript">
        window.onload = function(){
            var body = document.getElementsByTagName("body")[0];
            var text,table,tr,td;
            var count = 1000;
            console.time("DOM");
            for(var i = 0 ; i<count ; i++){
                    text = document.createTextNode("text");
                    body.appendChild(text);
                    body.removeChild(text)
            }
            console.timeEnd("DOM");
            console.time("innerHTML");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "text";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML");
            //table structure
            console.time("DOM2");
            for(var i = 0 ; i<count ; i++){
                    table = document.createElement("table");
                    tr = document.createElement("tr");
                    td = document.createElement("td");
                    text = document.createTextNode("text");
                    table.appendChild(tr);
                    tr.appendChild(td);
                    td.appendChild(text);
                    body.appendChild(table);
                    body.removeChild(table);
            }
            console.timeEnd("DOM2");
            console.time("innerHTML2");
            for(var i = 0 ; i<count ; i++){
                body.innerHTML = "<table><tr><td>text</td></tr></table>";
                body.innerHTML = "";
            }
            console.timeEnd("innerHTML2");
        }
        </script>
    </head>

    <body/>
</html>

Я думаю, это означает, что DOM API лучше (с точки зрения производительности) для современных браузеров.

0
Peter Mortensen 29 Авг 2010 в 11:47

Я считаю, что innerHTML изначально был IE.

Я также думаю, что вы установили его, так как это не метод, так что второй пример будет

root.innerHTML = "<tr><td>some value</td></tr>";

Но отвечая на ваш вопрос, innerHTML удобнее, но часто говорят, что он медленнее. Однако KennyTM говорит в комментариях, что это намного быстрее.

Вы должны решить, стоит ли компромисс между производительностью, который, возможно, незначителен, стоить это способом DOM API или innerHTML.

0
Community 23 Май 2017 в 12:04

Как я уже упоминал в комментарии, innerHTML на самом деле быстрее, чем создание узлов DOM, но он неструктурирован.

Более быстрый метод, чем создание узлов DOM, но все еще структурированный, заключается в использовании табличных методов DOM 2 :

var tr = root.insertRow(-1);
var td = tr.insertCell(0);
var txt = document.createTextNode("some value");
td.appendChild(txt);
// or simply: td.innerHTML = "some value";
1
kennytm 10 Авг 2010 в 07:09

innerHTML определенно быстрее, чем DOM (см. Раздел обсуждения). Некоторое время назад я наткнулся на способ удобного написания больших HTML-структур с innerHTML, это немного лучше, чем конкатенация строк или необходимость писать большие структуры:

var html = [
   '<ul class="myclass">',
      '<li class="item">item1</li>',
      '<li class="item">item2</li>',
      '<li class="item">item3</li>',
      '<li class="item">item4</li>',
      '<li class="item">item5</li>',
   '</ul>'
].join("");

root.innerHTML =html;
2
naikus 10 Авг 2010 в 07:00

Я бы переупорядочил, чтобы сделать его более читабельным

var d = document;
td = d.createElement("td");
tr = d.createElement("tr");
td.appendChild( d.createTextNode("some value") );
tr.appendChild(td);
root.appendChild(tr);
0
Codler 10 Авг 2010 в 06:38