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

时间:2010-02-07 16:46:42

标签: jquery html

在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");

这可能很粗糙,因为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(''));

这似乎工作得很好,虽然在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>';

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

9 个答案:

答案 0 :(得分:60)

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

这是a link to the documentation

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

答案 1 :(得分:10)

您不必调用document.createElement:

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

jQuery中有各种有用的工具可用于扩展/修改DOM。例如,查看各种“wrap”方法。

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

答案 2 :(得分:8)

我倾向于查看jquery的模板引擎之一jQote

答案 3 :(得分: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>

然后使用...

检索它
var results = document.getElementById("results");
results.innerHTML = tmpl("item_tmpl", dataObject);

详情请见此处:
http://ejohn.org/blog/javascript-micro-templating/

答案 4 :(得分:3)

我个人认为代码的可读性和可编辑性比高性能更重要。无论你发现哪个更易于查看并进行更改而不破坏它应该是你选择的那个。

答案 5 :(得分:3)

我喜欢模板语言Handlebars.js

答案 6 :(得分:3)

如果JavaScript代码类似于HTML标记结构,则它更具可读性和可维护性。您可以使用$(&#39; div&#39;,{&#39; class&#39;:&#39; etc&#39;})来使用正式的jQuery路线...

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

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

这使得该方法更加灵活,您可以使用链接轻松地将事件处理程序,数据等添加到嵌套的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();

代码比使用官方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;
}

答案 7 :(得分:1)

自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);
});
<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>

答案 8 :(得分:0)

我正在做的方式如下所示。我不确定你是否应该创造这么多div,但它对我来说效果很好。

var div1 = $('<div class="colwrap_fof"></div>');        //THE COMPLEX DIV ITSELF
var div2 = $('<div class="homeimg"></div>');                
var div21 = $('<div id="backImageDiv'+fof_index+'" class="backDiv"></div>');
var div22 = $('<div id="frontImageDiv'+fof_index+'"  class="frontDiv"></div>');
div2.append(div21);
div2.append(div22);
div1.append(div2);
$("#df_background").append(div1);     // ADDING the complex div to the right place      

干杯,