使用jQuery创建HTML元素的最有效方法是什么?


425

最近,我一直在做很多模态窗口弹出窗口,而我没有使用jQuery。我用来在页面上创建新元素的方法绝大多数遵循以下原则:

$("<div></div>");

但是,我感到这不是执行此操作的最佳或最有效的方法。从性能的角度来看,在jQuery中创建元素的最佳方法是什么?

该答案具有以下建议的基准。


1
也尝试删除样式,看看是否可以加快速度。我发现CSS应用程序和更新对我来说在大页面上减慢的速度最大。
CVertex

3
提防过早的优化-如果您一次不对数百个DOM元素执行此操作,或者不使用非常旧的浏览器,那么您可能不会注意到浏览器性能的任何差异。
Blazemonger

1
@Blazemonger并不是很多,我需要一种更有效的创建DOM元素的方法,但是我所处的境地使我思考替代品是什么以及它们可能有多有效。
Darko Z

2
jQuery是一个库–出于这个原因,您几乎总是会产生开销性能开销:就像通过解释器与某人交谈。除非您想使用原始JavaScript,否则请充分利用编写$('<div>')并接受性能提升的速度。
Danny Bullis

1
jsben.ch/#/bgvCV <= 此基准测试应回答您的问题
EscapeNetscape

Answers:


307

我使用$(document.createElement('div')); 基准测试表明该技术是最快的。我推测这是因为jQuery不必将其标识为元素并创建元素本身。

您应该真正使用不同的Javascript引擎运行基准测试,并用结果权衡受众。从那里做出决定。


16
jQuery将其“附加”到DOM?哪里?这对我来说没有多大意义-div会去哪里?
斯特拉格

28
就像在javascript中一样,必须在jquery中添加已创建的div。$('<div>')本身不会附加到DOM,除非您将它附加到某些东西上。
Owen

6
@David-显然你是对的。我会注意到,大约2年前我刚开始学习jQuery时就添加了评论。您需要做一个appendTo...,因为注释显然是错误的,因此我将其删除。
tvanfosson

16
基准测试参考很好,但这也正在测试数以万计的元素的创建。在典型情况下,您什么时候才能处理这么多要素?与创建元素相比,您有更大的事情要担心。“ document.createElement”在0.097秒内运行39,682次“,而$('<div>')”在0.068秒内运行12,642次。我想说的是,如果某件事可以在一秒钟之内运行数千次,那么您是安全的。
Danny Bullis

20
此外,使用$(document.createElement('div')); 我要说的是效率较低,因为如果一次又一次只创建一个元素,那么花更长的时间才能在浏览器中获得很少的好处。从技术上讲,由于查找成本以及使用它所产生的开销,jQuery本身作为库的效率较低。如果有人打算使用document.createElement而不是$('<div>')来节省千分之一毫秒,那么他们不应该使用jQuery:],因为$('<div>')是您使用它的原因之一!
Danny Bullis

163

我个人建议(出于可读性):

$('<div>');

到目前为止,有关建议的一些数字(Safari 3.2.1 / mac os x):

var it = 50000;

var start = new Date().getTime();
for (i = 0; i < it; ++i)  {
  // test creation of an element 
  // see below statements
}
var end = new Date().getTime();
alert( end - start );                

var e = $( document.createElement('div') );  // ~300ms
var e = $('<div>');                          // ~3100ms
var e = $('<div></div>');                    // ~3200ms
var e = $('<div/>');                         // ~3500ms              

15
来自jquery文档:'创建单个元素时,请使用结束标记或XHTML格式。例如,要创建跨度,请使用$(“ <span />”)或$(“ <span> </ span>”)而不是不使用斜杠/标记。
tvanfosson

6
@Owen,这种行为是错误,而不是功能。垃圾进,垃圾出-碰巧您得到的垃圾是可以接受的。但是,除非函数的规范发生更改,否则不要在jQuery版本之间依赖它。
斯特拉格

2
不出所料,在Mac OS X Chrome(100毫秒用于createElement()与500毫秒的文本解析)和Mac OS X Firefox(350毫秒与1000毫秒)中看到了相似的数字。感谢您编写测试循环。
Annika Backstrom,2010年

3
@tvanfosson显然已经改变了,在当前文档中它说:“当参数具有单个标签(带有可选的关闭标签或快速关闭)时— $(“ <img />”)或$(“ <img>” ),$(“ <a> </a>”)或$(“ <a>”)— jQuery使用本机JavaScript createElement()函数创建元素。”
metatron 2013年

3
@MarcStober没有采取任何进攻。它仍然在这里:http : //api.jquery.com/jQuery/#jQuery2。文档提到可选的关闭标签或快速关闭
metatron

155

题:

使用jQuery创建HTML元素的最有效方法是什么?

回答:

既然如此,jQuery我认为最好使用这种(干净的)方法(您正在使用)

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'text':'Text Only',
}).on('click', function(){
    alert(this.id); // myDiv
}).appendTo('body');

演示。

这样,您甚至可以对特定元素使用事件处理程序,例如

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'style':'cursor:pointer;font-weight:bold;',
    'html':'<span>For HTML</span>',
    'click':function(){ alert(this.id) },
    'mouseenter':function(){ $(this).css('color', 'red'); },
    'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');

演示。

但是,当您处理大量动态元素时,应避免handlers在特定元素中添加事件,而应使用委托事件处理程序,例如

$(document).on('click', '.myClass', function(){
    alert(this.innerHTML);
});

var i=1;
for(;i<=200;i++){
    $('<div/>', {
        'class':'myClass',
        'html':'<span>Element'+i+'</span>'
    }).appendTo('body');
}

演示。

因此,如果您创建并追加具有相同类(即(myClass))的数百个元素,则将更少的内存用于事件处理,因为只有一个处理程序可以为所有动态插入的元素完成这项工作。

更新:由于我们可以使用以下方法来创建动态元素

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    'size': '30'
}).appendTo("body");

size属性不能使用使用这种方法进行设置jQuery-1.8.0或更高版本,这里是一个老的bug报告,看看这个例子中使用jQuery-1.7.2这表明size属性被设置为30使用上面的例子,但使用相同的方法,我们不能设置size使用属性jQuery-1.8.3,在这里是一个不工作的小提琴。因此,要设置size属性,我们可以使用以下方法

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    attr: { size: "30" }
}).appendTo("body");

还是这个

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    prop: { size: "30" }
}).appendTo("body");

我们可以通过attr/prop为子对象,但它的工作原理jQuery-1.8.0 and later版本检查这个例子,但它是行不通jQuery-1.7.2 or earlier(在所有早期版本未测试)。

BTW,取自jQuery错误报告

有几种解决方案。第一个是根本不使用它,因为它不会节省您任何空间,并且可以提高代码的清晰度:

他们建议使用以下方法(也适用于较早的方法,已在中进行测试1.6.4

$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");

因此,最好使用这种方法,IMO。此更新是在我阅读/找到此答案后进行的,并且在此答案中显示,如果您使用'Size'(capital S)而不是,'size'它将正常工作,即使在version-2.0.2

$('<input>', {
    'type' : 'text',
    'Size' : '50', // size won't work
    'autofocus' : 'true'
}).appendTo('body');

另请阅读有关prop的信息,因为存在差异,Attributes vs. Properties不同版本的差异也有所不同。


$('<div />',{.........})是什么类型的罪过,我一直在寻找,使用$('<div>)。attr( {......})?
拉斐尔·鲁伊斯·塔巴雷斯

@RafaelRuizTabares,$('<div>', {...})正在传递包含所有属性的对象,并$('<div>').attr({...})正在创建不包含任何属性的元素,但attr()稍后使用方法设置属性。
Alpha 2015年

@TheAlpha在哪里可以找到有关我可以在{}中编写的内容的信息?因为我看到它们是属性和事件,但对于<div>,您也使用html。谢谢!
拉斐尔·鲁伊兹·塔巴雷斯

搜索jQuery.com网站可能会对@RafaelRuizTabares有所帮助,或者对它进行谷歌搜索:-)
The Alpha

2
到目前为止,这是最干净,更易读的方式!可能不是最快的方法,但肯定会减少错误,因此容易增加字符串。感谢@TheAlpha
Ares

37

实际上,如果您这样做$('<div>'),jQuery也将使用document.createElement()

(只需看一下第117行)。

有一些函数调用开销,但是除非性能至关重要(要创建成百上千个元素),否则没有太多理由恢复为纯DOM

仅为新网页创建元素可能是您最好坚持使用jQuery做事方式的一种情况。


20

如果您有很多HTML内容(不只是一个div),则可以考虑将HTML构建到隐藏容器内的页面中,然后对其进行更新并在需要时使其可见。这样,您的标记的很大一部分可以由浏览器预先解析,并且避免在调用时陷入JavaScript的泥潭。希望这可以帮助!


感谢您的建议。我以前使用过这种方法,但是在这种特殊情况下,我特别想了解有关创建元素的信息。
Darko Z

20

这不是问题的正确答案,但我仍然想分享一下...

document.createElement('div')当您要动态制作大量元素并追加到DOM时,使用just 和skip JQuery将大大提高性能。


16

我认为您正在使用最佳方法,尽管可以将其优化为:

 $("<div/>");

11

从CPU的角度来看,您不需要从原始操作中获得很少性能的原始性能。


取决于您执行的频率。
Rich Bradshaw

8
OP正在创建模式弹出窗口。每秒不重复执行此操作数千次。相反,它可能最多每隔几秒钟重复一次。使用该jQuery(html :: String)方法非常好。除非情况极为不同寻常,否则将不太可能获得更好的感知性能。将优化精力花在可以使用的案例上。此外,jQuery在许多方面都针对速度进行了优化。用它来做理智的事情,并信任但很快地验证它。
yfeldblum

9

您必须了解,元素创建性能的重要性与首先使用jQuery无关。

请记住,创建元素没有真正的目的,除非您实际要使用它。

您可能很想对诸如$(document.createElement('div'))vs.之类的产品进行性能测试,$('<div>')并从使用中获得巨大的性能提升,$(document.createElement('div'))但这只是DOM中尚不存在的一个元素。

但是,最终还是要使用该元素,因此实际测试应包括f.ex。.appendTo();

让我们看看,如果您对以下各项进行相互测试:

var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');

您会注意到结果会有所不同。有时,一种方法比另一种方法更好。这仅仅是因为计算机上的后台任务数量会随着时间而变化。

在这里测试自己

因此,最终,您确实想选择一种最小且最易读的创建元素的方式。这样,至少,您的脚本文件将最小。与在DOM中使用元素之前创建元素的方式相比,性能点上的影响可能更大。


我知道这已经很老了,但是在第一个示例中就不需要jQuery:document.getElementById('target).appendChild(document.createElement('div'));
散文


7

一点是,这样做可能会更容易:

$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")

然后使用jquery调用完成所有这些操作。


3

我正在使用jquery.min v2.0.3。对我来说,最好使用以下命令:

var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);

如下:

var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);

第一个代码的处理时间比第二个代码要短得多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.