58

如果我需要创建几个嵌套的 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 依赖项一样。

4

6 回答 6

69

将它们写成长字符串,然后使用合适的 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.

于 2012-06-23T23:36:36.143 回答
22

我在研究其他东西时找到了这个解决方案。它是jQuery创建者的“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 ); 
于 2013-09-11T23:19:36.077 回答
21

我自己喜欢以下方法:

$('<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);
于 2012-06-23T23:06:01.320 回答
12

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

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与嵌套元素混合(例如,<p>Hello, <b>world!</b></p>。)在这种情况下,您可能需要使用其他技术之一,例如字符串文字。

于 2014-01-10T03:24:03.590 回答
8

我喜欢这种方法

    $("<div>", {class: "wrapper"}).append(
        $("<div>", {class: "inner"}).append(
            $("<span>").text(
                "Some text"
            )
        ), 
        $("<div>", {class: "inner"}).append(
            $("<span>").text(
                "Some text"
            )
        )
    ).appendTo("body")
于 2012-06-23T23:13:21.313 回答
1

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

'<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在客户端使用。这样你就可以减少不必要的噪音。

于 2013-08-26T15:26:07.973 回答