在jQuery中构建html元素的最简单方法

时间:2012-03-18 17:08:36

标签: javascript jquery coding-style element

我在jQuery中看到了很多不同的样式(以及几种不同的方法)。我很好奇最清晰的构建它们的方式,以及任何特定方法因任何原因客观上比另一方法更好。以下是我见过的样式和方法的一些示例

var title = "Title";
var content = "Lorem ipsum";

// escaping endlines for a multi-line string
// (aligning the slashes is marginally prettier but can add a lot of whitespace)
var $element1 = $("\
    <div><h1>" + title + "</h1>\
        <div class='content'>  \
        " + content + "        \
        </div>                 \
    </div>                     \
");

// all in one
// obviously deficient
var $element2 = $("<div><h1>" + title + "</h1><div class='content'>" + content + "</div></div>");

// broken on concatenation
var $element3 = $("<div><h1>" +
                title + 
                "</h1><div class='content'>" +
                content +
                "</div></div>");

// constructed piecewise
// (I've seen this with nested function calls instead of temp variables)
var $element4 = $("<div></div>");
var $title = $("<h1></h1>").html(title);
var $content = $("<div class='content'></div>").html(content);
$element4.append($title, $content);

$("body").append($element1, $element2, $element3, $element4);

请随意展示您可能使用的任何其他方法/样式。

10 个答案:

答案 0 :(得分:68)

模板非常棒,如果您可以在项目中访问它们,我建议您使用它们。如果您正在使用内置的UnderscoreLodash。但在某些情况下,您需要在代码中构建HTML,无论是重构还是测试。我发现当需要时,下面的格式是最清楚的。

注意:HTML spec允许标记中的属性使用单引号或双引号,因此不要为所有疯狂的转义而烦恼。

this.$fixture = $([
  "<div>",
  "  <div class='js-alert-box'></div>",
  "  <form id='my-form-to-validate'>",
  "    <input id='login-username' name='login-username'>",
  "  </form>",
  "</div>"
].join("\n"));

答案 1 :(得分:45)

环顾四周后,我发现了我最终确定的风格。首先,我会说我使用Mustache进行模板化,效果很好。但有时候,你只需要一次构建一个元素,而不需要重用它,或者有其他动机不要引入另一个库。在这种情况下,我已经开始使用:

$("body")
.append(
    $("<div>")
    .append(
        $("<div>")
        .append(
            $("<h1>").text(title)
        )
    )
    .append(
        $("<div>").text(content)
    )
);​

这是有效的,因为append()会返回对您追加 的对象的引用,因此链式append()会附加到同一个对象。通过适当的缩进,标记的结构是显而易见的,这样很容易修改。显然这比使用模板慢(整个事情必须逐个构建),但如果你只是用它来进行初始化或类似的事情,那么这是一个很好的妥协。

有很多方法可以格式化这样的构造,但我选择了一种方法来清楚地说明发生了什么。我使用的规则是每行最多应有一个左括号和/或一个右括号。此外,这些追加树的叶子不需要传递给jQuery构造函数,但我在这里做了视觉重复。

答案 2 :(得分:29)

当谈到DOM构建时,我尽量避免字符串连接,因为它们可能会导致细微的错误和非正确编码的输出。

我喜欢这个:

$('<div/>', {
    html: $('<h1/>', {
        html: title
    }).after(
        $('<div/>', {
            'text': content,
            'class': 'content'
        })
    )
}).appendTo('body');

产生

    ...
    <div><h1>some title</h1><div class="content">some content</div></div>
</body>

它确保正确的HTML编码和DOM树构建以及匹配的开始和结束标记。

答案 3 :(得分:23)

我的建议:不要尝试用jQuery构建html元素,这不是它的责任。

使用Javascript模板系统,例如MustacheHandlebarJs

使用非常有限的行数,您可以直接从Javascript对象创建html元素。它并不复杂,只有2个函数和一个模板。

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>

var context  = {title: "My New Post", body: "This is my first post!"}
var template = Handlebars.compile($("#template-skeleton"));
var html     = template(context);

修改
另一个没有html的例子,纯Javascript(来自ICanHaz):

var skeleton = '<div><h1>{{title}}</h1><div class="content">{{content}}</div></div>';
var data = { title: "Some title", content: "Some content" };
var html = Mustache.to_html(skeleton, data);

它比一系列连接更易于维护。

答案 4 :(得分:11)

2015回答:对于旧版浏览器,请使用multiline

var str = multiline(function(){/*
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>
*/});

对于ES6,请使用JavaScript template strings

var str = `
<!doctype html>
<html>
    <body>
        <h1>❤ unicorns</h1>
    </body>
</html>`

答案 5 :(得分:6)

这是根据贝尔的回答改编的。我觉得它更具可读性,不需要创建和加入数组,不需要在每一行都加上引号:

http://jsfiddle.net/emza5Ljb/

var html =

    '                                                           \
      <div>                                                     \
        <div class="js-alert-box"></div>                        \
        <form id="my-form-to-validate">                         \
          <input id="login-username" name="login-username">     \
        </form>                                                 \
      </div>                                                    \
    '

// using jQuery:
//
var dom = $( html )

// or if you need performance, don't use jQuery
// for the parsing.
// http://jsperf.com/create-dom-innerhtml-vs-jquery
//
var div       = document.createElement( 'div' )
div.innerHTML = html
var dom = $( div )

仅供参考,当性能不是问题且元素包含大量动态数据时,我有时只会编写这样的代码(请注意,闭包编译器会对不带引号的类属性发出警告,但在现代浏览器中这是工作正常):

$(
      '<a></a>'

    , {
           text     : this.fileName
         , href     : this.fileUrl
         , target   : '_blank'
         , class    : 'file-link'
         , appendTo : this.container
      }
)

答案 6 :(得分:2)

答案 7 :(得分:2)

我发现功能方法非常方便。例如

// reusable generics TABLE constructor helpers
var TD = function(content) { return $('<td>', { html: content }) }
var TH = function(content) { return $('<th>', { html: content }) }
var TR = function(cell, cells) {  // note the kind of cell is a 2^order parameter
    return $('<tr>', { html: $.map(cells, cell) })
}

// application example
THEAD = $('<thead>', {html:
    TR(TH, [1,2,3,4])})
TBODY = $('<tbody>', {html: [
    TR(TD, ['a','b','c','d']),
    TR(TD, ['a','b','c','d']),
]})

现在来电

$('#table').append($('<table>', {html: [THEAD, TBODY]}))

产量

&#13;
&#13;
<table><thead><tr><th>1</th><th>2</th><th>3</th><th>4</th></tr></thead><tbody><tr><td>a</td><td>b</td><td>c</td><td>d</td></tr><tr><td>a</td><td>b</td><td>c</td><td>d</td></tr></tbody></table>
&#13;
&#13;
&#13;

修改

我已经改进了我的方法,现在可用作html_uty.js

答案 8 :(得分:2)

以下是使用$(htmlString)并模仿HTML代码标准布局的示例:

function getPage(title, contents) {
  return (
    $("<div>", {id: "container", class: "box"}).append(
      $("<div>", {class: "title"}).append(
        $("<h1>").text(title)
      ),
      $("<div>").html(contents)
    )
  );
}

答案 9 :(得分:0)

最简单的方法-

var optionsForLength = 
'<option value="Kilometre">Kilometre</option>'+
'<option value="Metre">Metre</option>'+
'<option value="Centimetre">Centimetre</option>'+
'<option value="Milimetre">Milimetre</option>'+
'<option value="Micrometre">Micrometre</option>'+
'<option value="Nanometre">Nanometre</option>'+
'<option value="Mile">Mile</option>'+
'<option value="Yard">Yard</option>'+
'<option value="Foot">Foot</option>'+
'<option value="Inch">Inch</option>'+
'<option value="Nautical mile">Nautical mile</option>';