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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:02:27  来源:igfitidea点击:

jQuery - Best Practice for creating complex HTML Fragments

jqueryhtml

提问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 innerHTMLproperty on an element. But as far as readability goes; the jQuery-approach is my favorite. And in most cases the performance-gain of using innerHTMLis 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

I'd be inclined to look at one of the templating engines for jquery like jQote

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

回答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,

干杯,