jQuery - 创建复杂 HTML 片段的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2217409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery - Best Practice for creating complex HTML Fragments
提问by Ryan Elkins
Is there a general best practice for creating somewhat complex HTML elements in jQuery? I've tried a few different ways.
在 jQuery 中创建有些复杂的 HTML 元素是否有一般的最佳实践?我尝试了几种不同的方法。
First I tried using createElement and chaining alot of those together with AppendTo and the like:
首先,我尝试使用 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");
This can be rough since appendTo wants to add to every matching element so everything needs its own name otherwise it ends up getting added repeatedly all over the place.
这可能很粗糙,因为 appendTo 想要添加到每个匹配的元素,所以一切都需要自己的名称,否则最终会在整个地方重复添加。
Then I tried creating an array and joining it together:
然后我尝试创建一个数组并将其连接在一起:
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(''));
This seems to work pretty well, although in IE when I would put an alert($(badgeFragment).text()) it usually came back empty. (This was part of debugging a larger problem). I'm obviously a bit new to jQuery (And even Javascript really) so to try and make sure this wasn't the problem I tried a third method - giant string concatenation:
这似乎工作得很好,尽管在 IE 中,当我放置 alert($(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>';
Is one of these methods generally considered better than the others? I'm not really good with the various profilers so I'm not sure how to verify this myself. There is also the question of how whether or not all of these methods are cross browser compliant.
这些方法中的一种是否通常被认为比其他方法更好?我不太擅长使用各种分析器,所以我不确定如何自己验证这一点。还有一个问题是所有这些方法是否都兼容跨浏览器。
回答by cllpse
With jQuery 1.4, you can create HTML elements like so:
使用 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);
Here's a link to the documentation.
这是文档的链接。
I'm not sure that this approach is faster than using the html()
function of jQuery. Or faster than skipping jQuery all together and use the innerHTML
property on an element. But as far as readability goes; the jQuery-approach is my favorite. And in most cases the performance-gain of using innerHTML
is marginal.
我不确定这种方法是否比使用html()
jQuery的功能更快。或者比一起跳过 jQuery 并innerHTML
在元素上使用属性更快。但就可读性而言;jQuery 方法是我的最爱。在大多数情况下,使用的性能增益innerHTML
是微不足道的。
回答by Pointy
You don't have to call document.createElement:
您不必调用 document.createElement:
$('#existingContainer').append(
$('<div/>')
.attr("id", "newDiv1")
.addClass("newDiv purple bloated")
.append("<span/>")
.text("hello world")
);
There are all sorts of useful tools in jQuery for extending/ammending the DOM. Look at the various "wrap" methods for example.
jQuery 中有各种有用的工具来扩展/修改 DOM。例如,查看各种“包装”方法。
Another possibility: for really big blobs of new content, you may be better off having your server prepare those (using the server-side templating system, whatever that is for you) and fetching those with $.load()
or some other ajax approach.
另一种可能性:对于非常大的新内容,您最好让服务器准备这些(使用服务器端模板系统,无论是什么)并使用$.load()
或其他一些ajax方法获取它们。
回答by lomaxx
回答by Simon East
John Resig (creator of jQuery) suggested using this templating method back in 2008. It's actually got some pretty cool features:
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>
then retrieving it using...
然后使用...检索它
var results = document.getElementById("results");
results.innerHTML = tmpl("item_tmpl", dataObject);
See here for full details:
http://ejohn.org/blog/javascript-micro-templating/
有关完整详细信息,请参见此处:http: //ejohn.org/blog/javascript-micro-templating/
回答by Http.Code.301
It is more readable and maintainable if the JavaScript code resembles the HTML tag structure. You can go the official jQuery route using $('div', { 'class': 'etc'})...
如果 JavaScript 代码类似于 HTML 标记结构,则它更具可读性和可维护性。你可以使用 $('div', { 'class': 'etc'}) 去官方的 jQuery 路线...
Here is a slightly different approach using a function $$ to make each element an editable jQuery object. It should be pretty fast as there is no html parsing taking place.
这是使用函数 $$ 使每个元素成为可编辑的 jQuery 对象的略有不同的方法。它应该非常快,因为没有进行 html 解析。
$$('div', {'id':'container'},
$$('div', {'id':'my_div'},
$$('h1',{'class':'my_header'},
$$('a',{'href':'/test/', 'class':'my_a_class'}, 'teststring'))));
This makes the approach more flexible and you can add event handlers, data etc. to the nested jQuery objects using chaining quite easily e.g.
这使得该方法更加灵活,您可以使用链接很容易地将事件处理程序、数据等添加到嵌套的 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();
The code is more readable than if one were to use the official jQuery approach of doing it with separate calls to .append(), .text(), .html() etc. or by feeding the jQuery $ a concatenated HTML string.
与使用官方 jQuery 方法(通过单独调用 .append()、.text()、.html() 等或通过向 jQuery $ 提供连接的 HTML 字符串)相比,该代码更具可读性。
Reference function $$:
参考函数$$:
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;
}
回答by Lars-Lasse
Since HTML5 there's the <template>
tag.
由于 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>
回答by Skilldrick
I personally think that it's more important for the code to be readable and editable than performant. Whichever one you find easier to look at and make changes to without breaking it should be the one you choose.
我个人认为代码的可读性和可编辑性比性能更重要。无论您发现哪一个更容易查看并在不破坏它的情况下对其进行更改,都应该是您选择的那个。
回答by cdmo
I like the templating language Handlebars.js
我喜欢模板语言Handlebars.js
回答by marcelosalloum
The way I am doing is shown bellow. I am not sure if u should create so many divs but it worked pretty well with me.
我正在做的方式如下所示。我不确定你是否应该创建这么多 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
Cheers,
干杯,