jQuery - 创建复杂HTML片段的最佳实践

Rya*_*ins 56 html jquery

在jQuery中创建一些复杂的HTML元素是否有一般的最佳实践?我尝试了几种不同的方法.

首先,我尝试使用createElement并将其与AppendTo等链接在一起:

var badge = $(document.createElement("div")).attr("class", "wrapper1").appendTo("body");
$(document.createElement("div")).attr("class", "wrapper2").appendTo(".wrapper1");
$(document.createElement("table")).attr("class", "badgeBody").appendTo(".wrapper2");
$(document.createElement("tr")).attr("class", "row1").appendTo(".badgeBody");
$(document.createElement("td")).appendTo(".row1");
$(document.createElement("span")).attr("class", "badgeUnlocked").text("UNLOCKED! ").appendTo("td");
$(document.createElement("td")).attr("class", "badgeTitleText").appendTo(".row1");
$(document.createElement("span")).attr("class", "badgeTitle").text(name).appendTo(".badgeTitleText");
$(document.createElement("tr")).attr("class", "row2").appendTo(".badgeBody");
$(document.createElement("td")).appendTo(".row2");
$(document.createElement("img")).attr("src", imgUrl).appendTo(".row2 td");
$(document.createElement("td")).attr("class", "badgeText").appendTo(".row2");
$(document.createElement("span")).attr("class", "badgeDescription").text(description).appendTo(".badgeText");
Run Code Online (Sandbox Code Playgroud)

这可能很粗糙,因为appendTo想要添加到每个匹配元素,所以一切都需要自己的名字,否则它最终会在整个地方重复添加.

然后我尝试创建一个数组并将它们连接在一起:

var badgeFragment = [
'<div><div id="'+ closeId+'" class="closeTab">X</div>',
'<div id="'+ badgeId+'" class="wrapper1">',
'<div class="wrapper2">',
'<div class="badgeBody">',
'<div class="badgeImage">',
'<img src="'+ imgUrl +'">',
'</div>',
'<div class="badgeContents">',
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>',
'<div class="badgeTitle">'+ name +'</div>',
'<div id="'+ textId+'" class="badgeDescription">'+ description +'</div>',
'</div>',
'<div style="clear:both"></div>',
'</div></div></div></div></div>',
]

badgeFragment = $(badgeFragment.join(''));
Run Code Online (Sandbox Code Playgroud)

这似乎工作得很好,虽然在IE中,当我发出警报($(badgeFragment).text())时,它通常会变回空白.(这是调试更大问题的一部分).我显然对jQuery有点新鲜(甚至Javascript真的)所以试着确保这不是问题我尝试了第三种方法 - 巨型字符串连接:

var badgeFragment =
'<div><div id="'+ closeId+'" class="closeTab">X</div>' +
'<div id="'+ badgeId+'" class="wrapper1">' +
'<div class="wrapper2">' +
'<div class="badgeBody">' +
'<div class="badgeImage">' +
'<img src="C:/Users/Ryan/Documents/icons/crystal_project/64x64/apps/chat.png">' +
'</div>' +
'<div class="badgeContents">' +
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>' +
'<div class="badgeTitle">test</div>' +
'<div id="'+ textId+'" class="badgeDescription">test</div>' +
'</div>' +
'<div style="clear:both"></div>' +
'</div></div></div></div></div>';
Run Code Online (Sandbox Code Playgroud)

这些方法中的一种通常被认为比其他方法更好吗?我对各种剖析器并不是很好,所以我不确定如何自己验证.还有一个问题是所有这些方法是否都符合浏览器标准.

cll*_*pse 63

使用jQuery 1.4,您可以像这样创建HTML元素:

// create an element with an object literal, defining properties
var e = $("<a />", {
    href: "#",
    "class": "a-class another-class", // you need to quote "class" since it's a reserved keyword
    title: "..."
});

// add the element to the body
$("body").append(e);
Run Code Online (Sandbox Code Playgroud)

这是文档的链接.

我不确定这种方法比使用html()jQuery 的功能更快.或者比一起跳过jQuery并innerHTML在元素上使用属性更快.但就可读性而言; jQuery方法是我的最爱.在大多数情况下,使用的性能增益innerHTML是微不足道的.

  • 如何用这种方法声明嵌套元素? (3认同)
  • @roosteronacid 取决于 [jQuery 文档](http://api.jquery.com/jQuery/)`名称“class”必须在对象中引用,因为它是 JavaScript 保留字`。 (2认同)
  • +1旨在提高可读性。这总是明智的,因为CPU速度会随着时间的流逝而增加,而对代码的了解却会减少。 (2认同)

Poi*_*nty 11

您不必调用document.createElement:

$('#existingContainer').append(
  $('<div/>')
    .attr("id", "newDiv1")
    .addClass("newDiv purple bloated")
    .append("<span/>")
      .text("hello world")
);
Run Code Online (Sandbox Code Playgroud)

jQuery中有各种有用的工具可用于扩展/修改DOM.例如,查看各种"包装"方法.

另一种可能性:对于真正大量的新内容,你可能最好让你的服务器做好准备(使用服务器端模板系统,无论你是什么),并使用$.load()或采用其他ajax方法.


lom*_*axx 8

我倾向于看一下像jQote这样的jquery的模板引擎


Sim*_*ast 7

John Resig(jQuery的创建者)建议在2008年使用这种模板方法.它实际上有一些非常酷的功能:

<script type="text/html" id="item_tmpl">

  <div id="<%=id%>" class="<%=(i % 2 == 1 ? " even" : "")%>">
    <div class="grid_1 alpha right">
      <img class="righted" src="<%=profile_image_url%>"/>
    </div>
    <div class="grid_6 omega contents">
      <p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p>
    </div>
  </div>

</script>
Run Code Online (Sandbox Code Playgroud)

然后使用...检索它

var results = document.getElementById("results");
results.innerHTML = tmpl("item_tmpl", dataObject);
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此处:http://ejohn.org/blog/javascript-micro-templating/

  • 如今,您可以更简单,更美观地使用[ICanHaz](http://icanhazjs.com/),它将这种方法与Mustache模板系统相结合,以获得更漂亮的模板和单行元素创建. (2认同)

小智 5

如果 JavaScript 代码类似于 HTML 标记结构,则它更具可读性和可维护性。你可以使用 $('div', { 'class': 'etc'}) 去官方的 jQuery 路线...

这是使用函数 $$ 使每个元素成为可编辑的 jQuery 对象的略有不同的方法。它应该非常快,因为没有进行 html 解析。

$$('div', {'id':'container'},
    $$('div', {'id':'my_div'},
        $$('h1',{'class':'my_header'},
            $$('a',{'href':'/test/', 'class':'my_a_class'}, 'teststring'))));
Run Code Online (Sandbox Code Playgroud)

这使得该方法更加灵活,您可以使用链接很容易地将事件处理程序、数据等添加到嵌套的 jQuery 对象中,例如

$$('div', {'id':'container'},
    $$('div', {'id':'my_div'},
        $$('h1',{'class':'my_header'},
            $$('a', { 'href': '/test/', 'class': 'my_a_class' }, 'teststring')
        ).click(function() { alert('clicking on the header'); })
    ).data('data for the div')
).hide();
Run Code Online (Sandbox Code Playgroud)

与使用官方 jQuery 方法通过单独调用 .append()、.text()、.html() 等或通过向 jQuery $ 提供连接的 HTML 字符串相比,该代码更具可读性。

参考函数$$:

function $$(tagName, attrTextOrElems) {
    // Get the arguments coming after the params argument
    var children = [];
    for (var _i = 0; _i < (arguments.length - 2) ; _i++) {
        children[_i] = arguments[_i + 2];
    }

    // Quick way of creating a javascript element without JQuery parsing a string and creating the element
    var elem = document.createElement(tagName);
    var $elem = $(elem);

    // Add any text, nested jQuery elements or attributes
    if (attrTextOrElems) {
        if (typeof attrTextOrElems === "string") { // text
            var text = document.createTextNode(attrTextOrElems);
            elem.appendChild(text);
        }
        else if (attrTextOrElems instanceof jQuery) { // JQuery elem
            $elem.append(attrTextOrElems);
        }
        else // Otherwise an object specifying attributes e.g. { 'class': 'someClass' }
        {
            for (var key in attrTextOrElems) {
                var val = attrTextOrElems[key];
                if (val) {
                    elem.setAttribute(key, val);
                }
            }
        }
    }

    // Add any further child elements or text    
    if (children) {
        for (var i = 0; i < children.length; i++) {
            var child = children[i];
            if (typeof child === "string") { // text
                var text = document.createTextNode(child);
                elem.appendChild(text);
            } else { // JQuery elem
                $elem.append(child);
            }
        }
    }
    return $elem;
}
Run Code Online (Sandbox Code Playgroud)


Lar*_*sse 5

由于 HTML5 有<template>标签。

$(function () {
    // Get template
    var template = $("#template").html();

    // Create a new row from the template
    var $row = $(template);

    // Add data to the row
    $row.find("td[data-template='firstName']").text("Foo");
    $row.find("td[data-template='lastName']").text("Bar");

    // Add the row to the table
    $("#table").append($row);
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<template id="template">
  <tr>
    <td data-template="firstName"></td>
    <td data-template="lastName"></td>
  </tr>
</template>

<table id="table">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
  </tr>
</table>
Run Code Online (Sandbox Code Playgroud)