21

我对如何插入大量 HTML 有一种不好的感觉。假设我们得到:

var html="<table>..<a-lot-of-other-tags />..</table>"

我想把它放进去

$("#mydiv")

以前我做过类似的事情

var html_obj = $(html); $("#mydiv").append(html_obj);

jQuery 正在解析html以创建 DOM-Objects 是否正确?好吧,这就是我在某处读到的(更新:我的意思是我已经读过,jQuery 解析 html 以手动创建整个 DOM 树 - 胡说八道吧?!,所以我更改了我的代码:

$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);

感觉更快,是吗?这是否等同于:

document.getElementById("mydiv").innerHTML += html? 还是 jquery 在后台做一些额外的昂贵的东西?

也很想学习替代品。

4

8 回答 8

33

尝试以下操作:

$("#mydiv").append(html);

其他答案,包括接受的答案,2-10x :jsperf

接受的答案在IE 6、7 和 8中不起作用,因为由于 IE: jsbininnerHTML中的错误,您无法设置元素。<table>

于 2010-12-12T09:57:58.297 回答
22

innerHTML 非常快,在许多情况下,您只需设置它就会得到最好的结果(我只会使用 append)。

但是,如果“mydiv”中已经有很多内容,那么您将强制浏览器再次解析和呈现所有这些内容(之前存在的所有内容,以及所有新内容)。 您可以通过将文档片段附加到“mydiv”来避免这种情况:

var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);

这样,只有您的新内容会被解析(不可避免),而现有内容不会。

编辑:我的错......我发现文档片段上的 innerHTML 没有得到很好的支持。您可以对任何节点类型使用相同的技术。对于您的示例,您可以创建根表节点并将 innerHTML 插入其中:

var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);
于 2008-09-22T22:22:32.137 回答
9

你试图避免什么?“不好的感觉”非常模糊。如果您听说过“DOM 很慢”并决定“避免使用 DOM”,那么这是不可能的。将代码插入页面的每种方法,包括 innerHTML,都会导致创建 DOM 对象。DOM 是文档在浏览器内存中的表示。您希望创建 DOM 对象。

人们之所以说“DOM 很慢”,是因为使用document.createElement()DOM 创建元素的官方接口比在某些浏览器中使用非标准的 innerHTML 属性要慢。这并不意味着创建 DOM 对象不好,创建 DOM 对象是必要的,否则你的代码根本不会做任何事情。

于 2008-09-22T21:17:01.687 回答
2

使用 DOM 片段的答案是正确的。如果您有一堆 html 对象不断插入到 DOM 中,那么您将看到使用该片段的一些速度改进。John Resig 的这篇文章很好地解释了这一点:http: //ejohn.org/blog/dom-documentfragments/

于 2008-09-27T03:04:06.643 回答
2

追加项目的最快方法

追加到 DOM 树的最快方法是将所有追加内容缓冲到单个 DOM 片段中,然后将 dom 片段追加到 dom。

这是我在游戏引擎中使用的方法。

//Returns a new Buffer object
function Buffer() {

    //the framgment
    var domFragment = document.createDocumentFragment();

    //Adds a node to the dom fragment
    function add(node) {
        domFragment.appendChild(node);
    }

    //Flushes the buffer to a node
    function flush(targetNode) {

        //if the target node is not given then use the body
        var targetNode = targetNode || document.body;

        //append the domFragment to the target
        targetNode.appendChild(domFragment);

    }

    //return the buffer
    return {
        "add": add,
        "flush": flush
    }
}


//to make a buffer do this
var buffer = Buffer();

//to add elements to the buffer do the following
buffer.add(someNode1);

//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);

//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);

使用这个对象,我可以在 Firefox 4 中每秒向屏幕渲染约 1000 个项目约 40 次。

这是一个用例。

于 2011-06-10T03:44:44.373 回答
1

对于初学者,编写一个脚本,计算每种方法执行 100 或 1,000 次所需的时间。

为了确保重复不会以某种方式被优化掉——我不是 JavaScript 引擎方面的专家——改变你每次插入的 html,比如把 '0001' 然后 '0002' 然后 '0003' 在某个表格的单元格。

于 2008-09-22T21:16:27.413 回答
0

我创建了一个巨大的字符串,然后用 jquery 附加这个字符串。对我来说效果很好,速度很快。

于 2012-08-28T14:32:54.123 回答
-1

你提到对替代品感兴趣。如果您查看与DOM 相关的 jQuery 插件列表,您会发现一些专用于以编程方式生成 DOM 树的插件。参见例如SuperFlyDomDOM Elements Creator;但还有其他人。

于 2008-09-22T21:59:04.893 回答