【问题标题】:jQuery document.createElement equivalent?jQuery document.createElement 等效?
【发布时间】:2010-09-21 01:48:27
【问题描述】:

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

但我不确定这是否更好。

【问题讨论】:

标签: javascript jquery html dom dhtml


【解决方案1】:

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

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

更新:我想我会更新这篇文章,因为它仍然有相当多的流量。在下面的 cmets 中有一些关于 $("&lt;div&gt;") vs $("&lt;div&gt;&lt;/div&gt;") vs $(document.createElement('div')) 作为创建新元素的方式的讨论,这是“最好的”。

我把a small benchmark放在一起,下面是大致重复以上选项10万次的结果:

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

【讨论】:

    【解决方案2】:

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

    例如:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我就是这样做的:

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

        【讨论】:

        • 为什么这个答案这么低?这是我最喜欢的!
        【解决方案5】:

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

        有两个好处:

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

        2.更重要的是,如果您使用旧方式,您可能会遭受跨站攻击(more info)。如果你有类似的东西:

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

        坏人可以输入&lt;script src="xss-attach.js"&gt;&lt;/script&gt;来逗你。幸运的是,$.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's answer 很好地说明了 parseHTML 对来自外部资源的 html 有好处,但是“在将结果包装在新的 jQuery 对象中之后,所有的提升都消失了”。也就是说,如果你想硬编码创建一个新的 jQuery 包装的 html 元素,$("&lt;div&gt;stuff&lt;/div&gt;") 样式似乎仍然是赢家。
        【解决方案6】:

        更新

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

        上一个答案

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

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

        【讨论】:

          【解决方案7】:

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

          从 jQuery 1.8 开始,有一个 jQuery.parseHTML() 函数,它现在是创建元素的首选方式。此外,通过$('(html code goes here)') 解析 HTML 存在一些问题,例如官方 jQuery 网站在one of their release notes 中提到以下内容:

          轻松的 HTML 解析:您可以再次使用前导空格或 $(htmlString) 中标签前的换行符。我们仍然强烈建议 解析从外部获取的 HTML 时使用 $.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 Link

          jQuery 1.9.1

          $.parseHTML:88 毫秒 $($.parseHTML):240 毫秒
          :138ms
          : 143 毫秒 创建元素:64 毫秒

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

          【讨论】:

            【解决方案8】:
            var mydiv = $('<div />') // also works
            

            【讨论】:

              【解决方案9】:
              var div = $('<div/>');
              div.append('Hello World!');
              

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

              【讨论】:

                【解决方案10】:

                我刚刚为此制作了一个小的 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 和 content 最好通过链式方法添加:

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

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

                【讨论】:

                  【解决方案11】:

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


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

                  【讨论】:

                    【解决方案12】:

                    在之前的答案中没有提到,所以我添加了如何使用最新的 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>

                    【讨论】:

                      【解决方案13】:

                      这又如何呢,例如当你想在&lt;select&gt; 中添加一个&lt;option&gt; 元素时

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

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

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

                      【讨论】:

                        【解决方案14】:

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

                        还有一些插件可以通过innerHTML 使用DOM,例如appendDOM、DOMEC 和FlyDOM,仅举几例。性能方面,原生 jquery 仍然是性能最高的(主要是因为它使用了 innerHTML)

                        【讨论】:

                        • 您应该了解最新情况。 jQuery 不使用 innerHtml 而是解析 HTML 字符串并在内部使用 document.createElement() 构建一个 DOM 树。这是核心 jQuery。
                        猜你喜欢
                        • 2021-12-09
                        • 2011-08-13
                        • 2015-05-27
                        • 1970-01-01
                        • 2011-05-27
                        • 2011-07-26
                        • 2013-10-08
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多