jQuerydocument.create元素等效?

我正在重构一些旧的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

但我不确定这是否更好。

1011778 次浏览

简单地提供要添加到jQuery构造函数$()的元素的超文本标记语言将从新构建的超文本标记语言返回一个jQuery对象,适合使用jQuery的append()方法附加到DOM中。

例如:

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

然后,如果您愿意,您可以以编程方式填充此表。

这使您能够指定任何您喜欢的超文本标记语言,包括类名或其他属性,您可能会发现这比使用createElement然后通过JS设置cellSpacingclassName等属性更简洁。

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

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    480mscreateElement    100ms      180ms    300ms

jQuery 1.3

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

jQuery 1.2

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

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


更新2

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

http://jsben.ch/#/ARUtz

开箱即用的jQuery没有createElement的等价物。事实上,jQuery的大部分工作都是在内部使用innerHTML而不是纯DOM操作完成的。正如Adam上面提到的,这就是实现类似结果的方法。

还有一些插件可以在innerHTML上使用DOM,例如appendDOMDOMECFlyDOM,仅举几例。在性能方面,原生jQuery仍然是性能最高的(主要是因为它使用了innerHTML)

这一切都很简单!这里有几个简单的例子…


var $example = $( XMLDocRoot );

var $element = $( $example[0].createElement('tag') );// Note the [0], which is the root
$element.attr({id: '1',hello: 'world'});

var $example.find('parent > child').append( $element );

创建新的DOM元素是jQuery()方法的核心特性,请参阅:

var mydiv = $('<div />') // also works
var div = $('<div/>');div.append('Hello World!');

是在jQuery中创建DIV元素的最短/最简单的方法。

我是这样做的:

$('<div/>',{text: 'Div text',class: 'className'}).appendTo('#parentDiv');

jQuery1.8开始,使用#1创建元素是更好的选择。

有两个好处:

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

2.much更重要的是,你可能遭受跨站点攻击(更多信息)如果你使用旧的方式。

    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>​]

更新

从最新版本的jQuery开始,以下方法不会分配在第二个Object中传递的属性

以前的答复

我觉得document.createElement('div')jQuery一起使用更快:

$(document.createElement('div'), {text: 'Div text','class': 'className'}).appendTo('#parentDiv');

我刚刚为此做了一个小jQuery插件:https://github.com/ern0/jquery.create

它遵循您的语法:

var myDiv = $.create("div");

DOM节点ID可以指定为第二个参数:

var secondItem = $.create("div","item2");

严重吗?不。但这种语法比$("

")
好,而且物有所值。

我是一个新的jQuery用户,从DOMAssistant切换,它有类似的功能:http://www.domassistant.com/documentation/DOMAssistantContent-module.php

我的插件更简单,我认为通过链接方法添加attrs和内容更好:

$("#container").append( $.create("div").addClass("box").html("Hello, world!") );

此外,它是一个简单的jQuery-plugin(第100个)的好例子。

虽然这是一个非常古老的问题,但我认为用最新的信息更新它会很好;

从jQuery 1.8开始,有一个jQuery.parse超文本标记语言()函数,它现在是创建元素的首选方式。此外,通过$('(html code goes here)')解析超文本标记语言存在一些问题,jQuery官方网站在他们的发行说明之一中提到了以下示例:

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

为了与实际问题相关,提供的示例可以翻译为:

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链接

jQuery 1.9.1

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

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

在之前的答案中没有提到,所以我添加了一个工作示例,如何使用最新的jQuery创建元素元素,以及附加属性,如内容、类或onClick回调:

const mountpoint = 'https://jsonplaceholder.typicode.com/users'
const $button = $('button')const $tbody = $('tbody')
const loadAndRender = () => {$.getJSON(mountpoint).then(data => {
$.each(data, (index, { id, username, name, email }) => {let row = $('<tr>').append($('<td>', { text: id })).append($('<td>', {text: username,class: 'click-me',on: {click: _ => {console.log(name)}}})).append($('<td>', { text: email }))
$tbody.append(row)})
})}
$button.on('click', loadAndRender)
.click-me {background-color: lightgrey}
<table style="width: 100%"><thead><tr><th>ID</th><th>Username</th><th>Email</th></tr></thead><tbody>  
</tbody></table>
<button>Load and render</button>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

这个怎么样,例如,当你想在<select>中添加<option>元素时

$('<option/>').val(optionVal).text('some option').appendTo('#mySelect')

你显然可以应用于任何元素

$('<div/>').css('border-color', red).text('some text').appendTo('#parentDiv')