代码之家  ›  专栏  ›  技术社区  ›  Harmen

您应该使用innerHTML向DOM添加HTML还是逐个创建新元素?

  •  17
  • Harmen  · 技术社区  · 16 年前

    有两种方法可以将HTML代码添加到DOM中,但我不知道什么是最好的方法。

    第一种方法很简单,我可以使用 $('[code here]').appendTo(element); element.innerHTML = [code here];

    第二种方法

    另一种方法是逐个创建所有元素,如:

    // New div-element
    var div = $('<div/>', {
                  id: 'someID',
                  class: 'someClassname'
              });
    
    // New p-element that appends to the previous div-element
    $('<p/>', {
        class: 'anotherClassname',
        text: 'Some textnode',
    }).appendTo(div);
    

    此方法使用的核心函数如下 document.createElement 和 element.setAttribute .

    我应该什么时候使用第一种方法,什么时候使用第二种方法?一种方法比两种方法快?

    编辑-结果 speed tests

    $(document).ready(function(){
        // jQuery method - Above mentioned as the second method
        $('#test_one').click(function(){
            startTimer();
            var inhere = $('#inhere');
            for(i=0; i<1000; i++){
                $(inhere).append($('<p/>', {'class': 'anotherClassname' + i, text: 'number' + i}));
            }
            endTimer();
            return false;
        });
    
        // I thought this was much like the jQuery method, but it was not, as mentioned in the comments
        $('#test_two').click(function(){
            startTimer();
            var inhere = document.getElementById('inhere');
            for(i=0; i<1000; i++){
                var el = document.createElement('p')
                el.setAttribute('class', 'anotherClassname' + i);
                el.appendChild(document.createTextNode('number' + i));
                inhere.appendChild(el);
            }
            endTimer();
            return false;
        });
    
        // This is the innerHTML method
        $('#test_three').click(function(){
            startTimer();
            var inhere = document.getElementById('inhere'), el;
            for(i=0; i<1000; i++){
                el += '<p class="anotherClassname' + i + '">number' + i + '</p>';
            }                
            inhere.innerHTML = el;
            endTimer();
            return false;
        });
    });
    

    得出了以下令人惊讶的结果

                   Test One   Test Two   Test Three  
    +-------------+---------+----------+------------+
    | Chrome    5 | ~125ms  |  ~10ms   |   ~15ms    |
    | Firefox 3.6 | ~365ms  |  ~35ms   |   ~23ms    |
    | IE        8 | ~828ms  |  ~125ms  |   ~15ms    |
    +-------------+---------+----------+------------+
    

    3 回复  |  直到 16 年前
        1
  •  2
  •   bmeck    16 年前

    我指的是一个过时的 article 为了让人们自己测试。 DOM方法实际上击败了我所有机器上的innerHTML,所以这是我喜欢的。然而,在本文发表之时,innerHTML在avg上的速度更快,目前这种差异只在巨大的数据集中才能看到。

        2
  •  2
  •   Andy E    16 年前

    实际上,这两种方法都没有用 innerHTML

    // If a single string is passed in and it's a single tag
    // just do a createElement and skip the rest
    if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
        var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
        if ( match )
            return [ context.createElement( match[1] ) ];
    }
    
    // ... some more code (shortened so nobody falls asleep) ...
    
    // Convert html string into DOM nodes
    if ( typeof elem === "string" ) {
        // Fix "XHTML"-style tags in all browsers
        elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
            return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
                all :
                front + "></" + tag + ">";
        });
        // etc...
    }
    

    一般来说,使用innerHTML比操作DOM慢,因为它调用HTML解析器(它将把HTML解析成DOM)。

        3
  •  0
  •   Patricia    16 年前

     $('body').append(the stuff)