jQuery document.createElement是否等效?


1251

我正在重构一些旧的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的基准测试
-EscapeNetscape


未被捕获的TypeError:$ .create不是函数
Tyguy7 '18

Answers:


1290

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

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

jQuery 1.3

                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


70
您会发现document.createElement比jQuery将html字符串转换为元素要快得多。(以防万一您有
急于

25
对于jQuery <1.3来说是正确的,我相信现在的速度已经相当。
罗布·史蒂文森-莱格特

15
@Kevin,是的,但是它使jQuery做更多的工作(通过正则表达式运行它以添加结束标记),因此我更喜欢上面的方法。此外,它还可以使您的代码与$('div')视觉上非常相似但功能截然不同的代码区分开。
尼克

14
因此,基本上将@Sungendran和@nickf组合在一起,$(document.createElement('div'))应该是最快的吗?
Kolky 2010年

14
我认为IMO的“正确”方法是$('<div />'),因为它显然是在创建Node,因此具有更多的“含义”。不好的是,这样会破坏所有编辑器中的语法突出显示=(
Erik Escobedo 2010年

139

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

例如:

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

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

这使您可以指定任何你喜欢的任意的HTML,包括类名或其他属性,您可能会发现更简洁比使用的能力createElement,然后设置类似的属性cellSpacing,并className通过JS。


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

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

2
@Adam jQuery对象具有get返回本机DOM元素的功能。(我知道这个话题很老,但是我添加为参考。;
Constantino Tsarouhas 2012年

1
如果您在使用html字符串时遇到问题,请尝试使用jQuery.parseHTML
fguillen 2013年

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


49

我这样做

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

44

由于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元素的创建进行硬编码,那么$("<div>stuff</div>")样式似乎仍然可以取胜。
ruffin

38

更新

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

先前的答案

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

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

29

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

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

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

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

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

不幸的是$(),这比使用just方便,但它给了您更多的控制权,例如,您可以选择排除脚本标签(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:88毫秒
  $($。parseHTML):240毫秒
  <div> </ div>:138ms
  <div>:143ms
  createElement:64毫秒

看起来parseHTML更接近createElement$(),但所有的提升是一个新的jQuery对象包装后的结果走了



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

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


5

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

它遵循您的语法:

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

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

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

严重吗 不会。但是此语法比$(“ <div> </ div>”)更好,并且对于这笔钱来说,这是非常好的价值。

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

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

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

另外,这也是一个简单的jQuery插件(第100个)的一个很好的例子。


4

一切都非常简单!这里有几个简单的例子...


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 );

1

在先前的答案中未提及,因此我添加了一个工作示例,该示例如何使用最新的jQuery创建元素元素,还具有诸如content,class或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>


-2

开箱即用的jQuery不具有createElement的等效项。实际上,大多数jQuery的工作都是在内部使用纯HTML而非纯DOM操作完成的。正如上文中亚当所提到的,这是您可以实现类似结果的方法。

还有一些可用的插件可以在innerHTML上使用DOM,例如appendDOMDOMECFlyDOM等等。在性能方面,本机jquery仍然是性能最高的(主要是因为它使用innerHTML)


5
您应该保持最新状态。jQuery不使用innerHtml,而是解析HTML字符串,并在内部使用document.createElement()构建DOM树。这是jQuery的核心。
文森特·罗伯特
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.