【问题标题】:What is the most efficient way to create HTML elements using jQuery?使用 jQuery 创建 HTML 元素的最有效方法是什么?
【发布时间】:2010-09-24 12:45:48
【问题描述】:

最近我一直在做很多模态窗口弹出窗口等等,为此我使用了 jQuery。我用来在页面上创建新元素的方法绝大多数是这样的:

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

但是,我感觉这不是最好或最有效的方法。从性能的角度来看,在 jQuery 中创建元素的最佳方式是什么?

This answer 具有以下建议的基准。

【问题讨论】:

  • 也尝试删除样式,看看这是否会加快速度。我发现 CSS 应用程序和更新对我来说在大页面上最慢。
  • 提防过早的优化——如果您不是一次对数百个 DOM 元素执行此操作,或者使用非常旧的浏览器,那么您可能不会注意到浏览器的任何差异性能。
  • @Blazemonger 并不是我需要一种更有效的创建 DOM 元素的方法,但是我所处的情况让我开始思考替代方案是什么,并且它们的效率如何。
  • jQuery 是一个库——由于这个原因,您几乎总是会产生开销性能成本:这就像通过解释器与某人交谈。除非您想使用原始 JavaScript,否则请利用编写 $('
    ') 的速度并接受性能损失。
  • jsben.ch/#/bgvCV 这个基准应该回答你的问题

标签: javascript jquery html dom


【解决方案1】:

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

 $("<div/>");

【讨论】:

    【解决方案2】:

    我个人建议(为了可读性):

    $('<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              
    

    【讨论】:

    • 来自 jquery 文档:'创建单个元素时使用结束标记或 XHTML 格式。例如,要创建跨度,请使用 $("") 或 $("") 而不是没有结束斜杠/标签。'
    • @Owen,这种行为是错误,而不是功能。垃圾进,垃圾出——碰巧你得到的垃圾是可以接受的。不过,不要在 jQuery 版本之间依赖它,除非函数的规范发生变化。
    • 正如预期的那样,在 Mac OS X Chrome(createElement() 的 100 毫秒与 500 毫秒的文本解析)和 Mac OS X Firefox(350 毫秒与 1000 毫秒)中看到了相似的数字。感谢您编写测试循环。
    • @tvanfosson 这显然已经改变了,在当前的文档中它说:“当参数有一个标签(带有可选的结束标签或快速关闭)- $( "" )或 $( "" )、$( "" ) 或 $( "" ) — jQuery 使用原生 JavaScript createElement() 函数创建元素。"
    • @MarcStober 没有冒犯。它还在这里:http://api.jquery.com/jQuery/#jQuery2。文档提到可选的结束标签或快速关闭
    【解决方案3】:

    我用$(document.createElement('div'));Benchmarking shows这个技术是最快的。我推测这是因为 jQuery 不必将其识别为元素并自行创建元素。

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

    【讨论】:

    • jQuery 将其“附加”到 DOM?在哪里?这对我来说没有多大意义—— div 会去哪里?
    • 必须像在 javascript 中一样添加在 jquery 中创建的 div。 $('
      ') 本身不会附加到 DOM,直到你 append() 它到某个东西。
    • @David - 显然你是对的。我会注意到我在大约 2 年前刚开始学习 jQuery 时添加了评论。你需要做一个appendTo,...因为 cmets 显然是错误的,我已经删除了它们。
    • 基准测试参考很棒,但这也是测试成千上万个元素的创建。在典型情况下,你什么时候会处理这么多元素?很有可能,您需要担心的事情比如何创建元素更重要。 document.createElement "在 0.097 秒内运行 39,682 次",而 $('
      ') "在 0.068 秒内运行 12,642 次。"我会说如果某样东西可以在不到一秒的时间内运行数千次,那么你就是安全的。
    • 此外,使用 $(document.createElement('div'));我会说效率较低,因为如果您一次只在这里和那里创建一个元素,那么您将在浏览器中获得的微不足道的好处需要更长的时间来编写。从技术上讲,由于查找成本和使用它所产生的开销,jQuery 本身作为一个库的效率较低。如果有人想通过使用 document.createElement 而不是 $('
      ') 来节省宝贵的千分之一毫秒,那么他们不应该使用 jQuery :],因为 $('
      ')是你使用它的原因之一!
    【解决方案4】:

    从 CPU 的角度来看,您将极少执行的操作不需要原始性能。

    【讨论】:

    • 取决于您执行此操作的频率。
    • OP 正在创建一个modal popup。此操作每秒不会重复数千次。相反,它最多每隔几秒重复一次。使用jQuery(html :: String) 方法非常好。除非情况非常不寻常,否则不太可能获得更好的感知性能。将优化精力花在可以使用它的案例上。此外,jQuery 在许多方面都针对速度进行了优化。用它做理智的事情,并相信但验证它是快速的。
    【解决方案5】:

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

    【讨论】:

    • 感谢您的建议。我以前使用过这种方法,但是在这种特殊情况下,我特别想了解如何创建元素。
    【解决方案6】:

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

    当您想要动态创建大量元素并附加到 DOM 时,仅使用 document.createElement('div') 并跳过 JQuery 将大大提高性能。

    【讨论】:

      【解决方案7】:

      实际上,如果你使用$('&lt;div&gt;'),jQuery 也会使用document.createElement()

      (看看line 117)。

      存在一些函数调用开销,但除非性能至关重要(您正在创建数百 [千] 个元素),否则没有太多理由恢复为普通的 DOM。。 p>

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

      【讨论】:

        【解决方案8】:

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

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

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

        【讨论】:

          【解决方案9】:

          有人已经做了基准测试: jQuery document.createElement equivalent?

          $(document.createElement('div')) 是大赢家。

          【讨论】:

            【解决方案10】:

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

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

            您可能很想对 $(document.createElement('div'))$('&lt;div&gt;') 进行性能测试,并通过使用 $(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');
            

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

            Test yourself here

            因此,归根结底,您确实希望选择最小且最易读的方式来创建元素。这样,至少,您的脚本文件将尽可能小。可能比在 DOM 中使用元素之前创建元素的方式更重要。

            【讨论】:

            • 我知道这是旧的,但在第一个示例中不需要 jQuery:document.getElementById('target).appendChild(document.createElement('div'));
            【解决方案11】:

            问题:

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

            答案:

            既然是关于jQuery,那么我认为最好使用这种(干净的)方法(你正在使用)

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

            DEMO.

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

            $('<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');
            

            DEMO.

            但是当您处理大量动态元素时,应避免在特定元素中添加事件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');
            }
            

            DEMO.

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

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

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

            但是size 属性不能使用jQuery-1.8.0 或更高版本使用这种方法设置,这是一个旧的bug report,请查看this example 使用jQuery-1.7.2,这表明size 属性已设置到30 使用上面的例子,但使用相同的方法我们不能使用jQuery-1.8.3 设置size 属性,这里是non-working fiddle。因此,要设置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 版本检查this example 但它在jQuery-1.7.2 or earlierwon't work(未在所有早期版本中测试)。

            顺便说一句,取自 jQuery 错误报告

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

            他们建议使用以下方法(works in earlier ones 也是,在 1.6.4 中测试过)

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

            所以,最好使用这种方法,IMO。此更新是在我阅读/找到this answer 之后进行的,并且在此答案中显示,如果您使用'Size'(capital S) 而不是'size',那么即使在version-2.0.2 中,它也只会是work fine

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

            另请参阅prop,因为有区别,Attributes vs. Properties,它因版本而异。

            【讨论】:

            • 这个 $('
              ', {.........}) 是什么类型的语法,我已经找过了,我发现了一些类似的使用 $( '
              ).attr({......}) ?
            • @RafaelRuizTabares,在$('&lt;div&gt;', {...}) 中,您正在传递一个包含所有属性的对象,在$('&lt;div&gt;').attr({...}) 中,您正在创建一个没有任何属性的元素,但稍后使用attr() 方法设置属性。
            • @TheAlpha 我在哪里可以找到关于我可以在 {} 中写入什么的信息?因为我看到它们是属性和事件,但是对于
              你也使用 html。谢谢!
            • 搜索jQuery.com 网站可能会有所帮助@RafaelRuizTabares,或者谷歌它:-)
            • 这是迄今为止最干净、更易读的方式!可能不是快速的方法,但字符串添加肯定更不容易出错。谢谢@TheAlpha
            【解决方案12】:

            我正在使用 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);
            

            第一个代码的处理时间远低于第二个代码。

            【讨论】:

              猜你喜欢
              相关资源
              最近更新 更多
              热门标签