我正在重构一些旧的JavaScript代码,并且正在进行许多DOM操作。

var d = document;
var odv = d.createElement("div");
odv.style.display = "none";
this.OuterDiv = odv;

var t = d.createElement("table");
t.cellSpacing = 0;
t.className = "text";
odv.appendChild(t);


我想知道是否有更好的方法可以使用jQuery的。我一直在尝试:

var odv = $.create("div");
$.append(odv);
// And many more


,但是我不确定这是否更好。

评论

jsben.ch/#/ARUtz-jQuery vs createElement的基准测试

在jQuery中创建div元素的可能重复项

未捕获的TypeError:$ .create不是函数

#1 楼

这是您在“一个”行中的示例。

this.$OuterDiv = $('<div></div>')
    .hide()
    .append($('<table></table>')
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;



更新:我想我会更新这篇文章,因为它仍然吸引了大量的访问量。在下面的评论中,有一些关于$("<div>") vs $("<div></div>") vs $(document.createElement('div'))的讨论,这是“最佳”的一种创建新元素的方式。

我整理了一个小基准,这大概是重复以上选项100,000次:

jQuery 1.4、1.5、1.6

               Chrome 11  Firefox 4   IE9
<div>            440ms      640ms    460ms
<div></div>      420ms      650ms    480ms
createElement    100ms      180ms    300ms



                Chrome 11
<div>             770ms
<div></div>      3800ms
createElement     100ms


jQuery 1.2

                Chrome 11
<div>            3500ms
<div></div>      3500ms
createElement     100ms


我认为这并不奇怪,但是document.createElement是最快的方法。当然,在开始重构整个代码库之前,请记住,我们在这里讨论的差异(除jQuery的旧版本以外,其他所有差异)相当于每千个元素额外多了3毫秒。


更新2

针对jQuery 1.7.2更新,并将基准放在JSBen.ch上,这可能比我的原始基准要科学得多,而且可以现在众包!

http://jsben.ch/#/ARUtz

评论


您会发现document.createElement比让jQuery将html字符串转换为元素快得多。 (以防万一您有提高工作效率的冲动)

– Sugendran
08年11月7日在7:19

对于jQuery <1.3来说是正确的,我相信现在的速度已经相当。

–罗布·史蒂文森-莱格特
09年2月2日在10:49

@Kevin,是的,但是它使jQuery做更多的工作(它通过正则表达式运行以添加结束标记),因此我更喜欢上面的方法。同样,它使您的代码与$('div')区别开来,后者在外观上非常相似,但在功能上却截然不同。

–nickf
2010-2-24在6:29

因此,基本上@Sungendran和@nickf的组合将是$(document.createElement('div')),它应该是最快的吗?

–高尔基
2010-3-12在17:59

我认为“正确”的方式是$('
'),IMO则具有更多的“含义”,因为创建节点很明显。不好的是,这样会破坏所有编辑器中的语法高亮显示=(

– Erik Escobedo
2010年7月7日15:51

#2 楼

只需提供要添加到jQuery构造函数$()的元素的HTML,即可从新建的HTML返回jQuery对象,适合使用jQuery的append()方法将其附加到DOM中。

例如:

var t = $("<table cellspacing='0' class='text'></table>");
$.append(t);


然后,您可以根据需要以编程方式填充此表。

这使您能够指定任意喜欢的HTML,包括类名称或其他属性,与使用createElement然后通过JS设置cellSpacingclassName等属性相比,您可能会发现更简洁。

评论


也许这很明显,并由您的示例表明,但是使用$(“ ”)语法创建jQuery DOM元素时,不能使用本机 .appendChild方法或类似方法将其附加到DOM中。您必须使用jQuery append方法。

–亚当
09年5月8日14:22

$(htmlStr)实现为document.createElement(“ div”)。innerHTML = htmlStr。换句话说,它调用浏览器的HTML解析器。格式错误的HTML在IE和其他浏览器中的中断方式不同。

–马修
2011年1月14日,0:28



@Adam jQuery对象具有get函数,该函数返回本机DOM元素。 (我知道这个主题很旧,但是我添加它作为参考。;-))

–康斯坦丁·萨鲁哈斯(Constantino Tsarouhas)
2012年5月17日20:36

如果您对html字符串有疑问,请尝试使用jQuery.parseHTML进行解析。

– fguillen
2013年9月4日17:43

@Adam或者,如果对您的代码流/眼睛更方便,可以执行[dom element] .appendChild($('')[0]);

– ACK_stoverflow
13-10-18在17:23

#3 楼

创建新的DOM元素是jQuery()方法的核心功能,请参见:


http://api.jquery.com/jQuery/#creating-new-elements
和特别http://api.jquery.com/jQuery/#example-1-1



#5 楼

因为jQuery1.8,使用$.parseHTML()来创建元素是更好的选择。

有两个好处:

1.如果使用旧方法,可能类似于$(string), jQuery将检查字符串以确保您要选择html标记或创建新元素。通过使用$.parseHTML(),您告诉jQuery您要显式创建一个新元素,因此性能可能会好一些。

2.更重要的是,您可能会遭受跨站点攻击(更多信息)(如果您使用旧方法)。如果您有类似问题:

    var userInput = window.prompt("please enter selector");
    $(userInput).hide();


坏人可以输入<script src="xss-attach.js"></script>来取笑您。幸运的是,$.parseHTML()为您避免了这种尴尬:

var a = $('<div>')
// a is [<div>​</div>​]
var b = $.parseHTML('<div>')
// b is [<div>​</div>​]
$('<script src="xss-attach.js"></script>')
// jQuery returns [<script src=​"xss-attach.js">​</script>​]
$.parseHTML('<script src="xss-attach.js"></script>')
// jQuery returns []


但是,请注意a是jQuery对象,而b是html元素:

a.html('123')
// [<div>​123​</div>​]
b.html('123')
// TypeError: Object [object HTMLDivElement] has no method 'html'
$(b).html('123')
// [<div>​123​</div>​]


评论


“更好的选择”到“创建[任何]元素”可能很强。 @siergiej的回答很好地说明了parseHTML对于来自外部来源的html很有好处,但是“将结果包装在新的jQuery对象中之后,所有的提升都消失了”。也就是说,如果您想对新的jQuery包装的html元素进行硬编码,则$(“
stuff
”)样式似乎仍然可以取胜。

–松饼
17-2-22在15:06

#7 楼

尽管这是一个非常老的问题,但我认为最好用最新信息进行更新;

自jQuery 1.8起,就有了jQuery.parseHTML()函数,该函数现在是创建元素的首选方式。此外,通过$('(html code goes here)')解析HTML也存在一些问题,例如,官方jQuery示例网站在其发行说明之一中提到了以下内容:


轻松的HTML解析:您可以再次使用前导空格或
$(htmlString)中的标记之前的换行符。我们仍然强烈建议
,在解析从外部
源获得的HTML时,请使用$ .parseHTML(),并且可能会在
将来对HTML解析进行进一步的更改。


为了解决实际问题,可以将提供的示例翻译为:

this.$OuterDiv = $($.parseHTML('<div></div>'))
    .hide()
    .append($($.parseHTML('<table></table>'))
        .attr({ cellSpacing : 0 })
        .addClass("text")
    )
;


不幸的是,它不如仅使用$()那样方便,但它让您有更多控制权,例如,您可以选择排除脚本标签(尽管它会留下诸如onclick之类的内联脚本):

> $.parseHTML('<div onclick="a"></div><script></script>')
[<div onclick=​"a">​</div>​]

> $.parseHTML('<div onclick="a"></div><script></script>', document, true)
[<div onclick=​"a">​</div>​, <script>​</script>​]


此外,这也是自上而下的基准适应新现实的答案:

JSbin Link

jQuery 1.9.1

  $.parseHTML:    88ms
  $($.parseHTML): 240ms
  <div></div>:    138ms
  <div>:          143ms
  createElement:  64ms


看起来像parseHTMLcreateElement更接近$(),但是将结果包装在新的jQuery对象中之后,所有的提升都消失了