Что лучше для манипулирования DOM - DOM API или innerHTML? - PullRequest
3 голосов
/ 10 августа 2010

У меня есть следующий код:

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).Как бы вы реализовали это, чтобы код был более читабельным?(Сейчас я разделяю код с комментариями.)

Ответы [ 9 ]

5 голосов
/ 10 августа 2010

Вы всегда можете написать функции-оболочки вокруг неуклюжего 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"')
]);
2 голосов
/ 10 августа 2010

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;
1 голос
/ 27 октября 2010

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

На моем телефоне Android есть несколько интересных результатов:

      DOM: 614 / 25
innerHTML: 697 / 542
      DOM: 546 / 18
innerHTML: 639 / 552
      DOM: 604 / 12
innerHTML: 641 / 534
      DOM: 619 / 11
innerHTML: 643 / 554
      DOM: 618 / 13
innerHTML: 655 / 600

Первыйчисло - это фактическое выполнение добавления 2700 li элементов.И еще более интересно - это второе число, то есть сколько времени требуется ol, чтобы стереть эти результаты, используя innerHTML = '';

Попробуйте сами на DOM противinnerHTML .

1 голос
/ 10 августа 2010

Как я уже упоминал в комментарии, 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";
0 голосов
/ 10 августа 2010

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

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

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

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

0 голосов
/ 10 августа 2010

Я сам написал несколько тестов, которые сравнивают 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 голосов
/ 10 августа 2010

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

var d = document;
td = d.createElement("td");
tr = d.createElement("tr");
td.appendChild( d.createTextNode("some value") );
tr.appendChild(td);
root.appendChild(tr);
0 голосов
/ 10 августа 2010

Использовать jQuery http://jquery.com/

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

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

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

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

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

0 голосов
/ 10 августа 2010

innerHTML изначально был IE, я думаю.

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

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

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

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

...