【问题标题】:Best way to create nested HTML elements with jQuery [closed]使用 jQuery 创建嵌套 HTML 元素的最佳方法 [关闭]
【发布时间】:2012-06-25 18:41:52
【问题描述】:

如果我需要创建几个嵌套的 DOM 元素,我知道一种方法,就是将它们写成长字符串,然后使用合适的 jQuery 函数将它们放入文档中。比如:

elem.html(
'<div class="wrapper">
    <div class="inner">
        <span>Some text<span>
    </div>
    <div class="inner">
        <span>Other text<span>
    </div>
</div>'); 

这种方式显然不是最干净的。刺痛不会花费太长时间而变得混乱,并且编辑成为一个问题。我更喜欢这种表示法:

$('<div></div>', {
    class : 'inner'
})
.appendTo( elem );

问题是我不知道如何在像上面那样动态创建嵌套元素时有效地实现它。所以如果有办法用第二种符号来做第一个例子,我会很高兴了解它。

基本上,问题是,动态创建嵌套 HTML 元素的最佳方法是什么,而不必处理凌乱的长字符串?

注意:我知道模板引擎。然而,这是一个关于动态创建几个 HTML 元素的问题。就像为插件或类似情况构建 DOM 依赖项一样。

【问题讨论】:

  • 您可以使用模板系统,或将“模板”存储在&lt;script type="text/template" id="magic-wrapper-template"&gt; 中并将其内容作为字符串检索。最后一种方法对我来说很容易。
  • Moustache 是您可以使用的模板库。
  • 谢谢,但我已经知道了。问题是您只需要动态创建几个元素的情况,例如在为插件或类似情况构建 dom 时。
  • 对一个人来说“最好”的东西可能不适合另一个人。尝试不同的方法并确定最适合您的方法
  • @charlietfl 我同意。但是你看,我只知道这种任务的一种方法,我不喜欢那种方法。所以我问这个问题是为了了解一些新的和更好的东西。

标签: javascript jquery dom nested


【解决方案1】:

我自己喜欢以下方法:

$('<div>',{
  'class' : 'wrapper',
  'html': $('<div>',{
    'class' : 'inner',
    'html' : $('<span>').text('Some text')
  }).add($('<div>',{
    'class' : 'inner',
    'html' : $('<span>').text('Other text')
  }))
}).appendTo('body');

或者,首先创建您的包装器,然后继续添加:

var $wrapper = $('<div>',{
    'class':'wrapper'
}).appendTo('body');
$('<div>',{
    'class':'inner',
    'html':$('<span>').text('Some text')
}).appendTo($wrapper);
$('<div>',{
    'class':'inner',
    'html':$('<span>').text('Other text')
}).appendTo($wrapper);

【讨论】:

  • 那是一张只有母亲才能爱的脸...:P 对我来说太细了。各有各的。
【解决方案2】:

我喜欢这种方法

    $("<div>", {class: "wrapper"}).append(
        $("<div>", {class: "inner"}).append(
            $("<span>").text(
                "Some text"
            )
        ), 
        $("<div>", {class: "inner"}).append(
            $("<span>").text(
                "Some text"
            )
        )
    ).appendTo("body")

【讨论】:

  • 我们可以在其中加入 onclick 和 onblur 事件吗?如果是,如何?
  • @ArunRaj 请参阅my answer 以获取示例。你可以做类似$text.click(function () { alert("You clicked on the span element."); });
【解决方案3】:

将它们写成长字符串,然后使用 合适的jQuery函数。比如:

这种方法的问题是你需要一个多行字符串——Javascript 不支持的东西——所以实际上你最终会得到:

elem.html(
'<div class="wrapper">'+
    '<div class="inner">'+
        '<span>Some text<span>'+
    '</div>'+
    '<div class="inner">'+
        '<span>Other text<span>'+
    '</div>'+
'</div>');

使用您上面建议的方法,这是我能做到的最干净的:

elem.append(
    $('<div/>', {'class': 'wrapper'}).append(
        $('<div/>', {'class': 'inner'}).append(
            $('<span/>', {text: 'Some text'})
        )
    )
    .append(
        $('<div/>', {'class': 'inner'}).append(
            $('<span/>', {text: 'Other text'})
        )
    )
);

这样做的另一个好处是,您可以(如果需要)直接引用每个新创建的元素,而无需重新查询 DOM。

我喜欢写polyglots,所以为了让我的代码可重复使用,我通常会这样做,(因为 jQuery 的 .html() 不支持 XML):

// Define shorthand utility method
$.extend({
    el: function(el, props) {
        var $el = $(document.createElement(el));
        $el.attr(props);
        return $el;
    }
});

elem.append(
    $.el('div', {'class': 'wrapper'}).append(
        $.el('div', {'class': 'inner'}).append(
            $.el('span').text('Some text')
        )
    )
    .append(
        $.el('div', {'class': 'inner'}).append(
            $.el('span').text('Other text')
        )
    )
);

这与方法 #2 没有太大区别,但它为您提供了更多可移植代码,并且在内部不依赖于 innerHTML

【讨论】:

  • 嗨,我认为最后一个使用实用方法的方法不对...不过我可能错了。首先,当您执行$.el('span', {text: 'Other text'}) 时,文本将是跨度的一个属性,而不是实际文本。其次,似乎您在内联执行的任何事件绑定,例如 $.el('div', {'class': 'inner'}).click(function(){alert('O hai');}); 似乎都没有触发......我可能正在做一些错误的事情
  • @Xeroxoid 你是对的。我猜这是/曾经是特定版本的 jQuery 未记录的东西(因此不稳定) - jquery 中有一个内部属性 - $.attrFn - 它是/已检查某些关键字(如“文本”)上的钩子函数,这就是它的目的。我马上更新...
  • 使用这个 extends 可以让你在没有选项的情况下使用 $.el('div')。 $.extend({ el: function(el, props) { var $el = $(document.createElement(el)); if(typeof(props) !== 'undefined'){ $el.attr(props); } 返回 $el; } });
  • 我想知道如何将多个元素添加为同级元素。我尝试使用.after() 方法,但我发现.append() 方法可以采用一个数组(在本例中为$.el() 数组)。 container.append([$.el('span').text('First'), $.el('span').text('Second')]);
  • .append() 可以采用数组,但也可以采用相同方式处理的无限数量的参数,因此您可以根据需要省略 [ 和 ]。跨度>
【解决方案4】:

长字符串显然是最干净的方式。您会看到正确嵌套的代码,没有括号、美元符号等不必要的额外噪音。当然,能够将其编写为多行字符串是有好处的,但目前还不可能。对我来说,重点是摆脱所有不需要的符号。我不知道字符串是如何变得凌乱的,并且编辑成为一个问题。如果你分配了很多类,你可以把它们放在单独的一行:

'<div id="id-1"'
+ ' class="class-1 class-2 class-3 class-4 class-5 class-6">'
+ '</div>'

或者这样:

'<div id="id-1" class="'
    + 'class-1 class-2 class-3 class-4 class-5 class-6'
+ '">'
+ '</div>'

如果可能的话,另一种选择可能是在客户端使用haml。这样您就可以减少不必要的噪音。

【讨论】:

    【解决方案5】:

    我在研究其他内容时发现了this solution。它是 jQuery 创建者 "Introduction to jQuery" 的一部分,并使用 end() 函数。

    $("<li><a></a></li>") // li 
      .find("a") // a 
      .attr("href", "http://ejohn.org/") // a 
      .html("John Resig") // a 
      .end() // li 
      .appendTo("ul");
    

    应用于您的问题将是......

    $("<div><span></span></div>") // div 
      .addClass("inner") // div 
      .find("span") // span 
      .html("whatever you want here.") // span 
      .end() // div 
      .appendTo( elem ); 
    

    【讨论】:

    • 介意引用任何来源??
    • @wardha-Web - 引用来源 - John Resig - ejohn.org
    • 谢谢,尽管指向您找到此解决方案的特定页面的确切链接可能会进一步增强信心。
    • 这是他 2010 年演讲中的参考资料:ejohn.org/apps/workshop/intro/#19
    • 感谢您的努力。
    【解决方案6】:

    除了长而丑陋的字符串或链接在一起的巨大方法之外,还有第三种方法。您可以使用plain old variables来保存单个元素:

    var $wrapper = $("<div/>", { class: "wrapper" }),
        $inner = $("<p/>", { class: "inner" }),
        $text = $("<span/>", { class: "text", text: "Some text" });
    

    然后,用append 将它们绑定在一起:

    $wrapper.append($inner.append($text)).appendTo("#whatever");
    

    结果:

    <div class="wrapper">
      <p class="inner">
        <span class="text">Some text</span>
      </p>
    </div>
    

    在我看来,这是迄今为止最简洁、最易读的方法,而且它还具有将数据与代码分离的优势。

    编辑: 但是,需要注意的是,没有简单的方法可以将 textContent 与嵌套元素(例如 &lt;p&gt;Hello, &lt;b&gt;world!&lt;/b&gt;&lt;/p&gt;)混合在一起。在这种情况下,您可能需要使用一个其他技术,例如字符串文字。

    【讨论】:

      猜你喜欢
      • 2012-03-13
      • 2015-02-13
      • 2013-01-09
      • 2013-04-19
      • 2012-01-15
      • 1970-01-01
      • 2010-09-24
      • 2011-01-13
      • 2011-05-14
      相关资源
      最近更新 更多