有使用javascript生成html的最佳实践吗

时间:2022-11-28 09:03:46

I'm calling a web service that returns an array of objects in JSON. I want to take those objects and populate a div with HTML. Let's say each object contains a url and a name.

我正在调用一个返回JSON对象数组的web服务。我想使用这些对象并用HTML填充div。假设每个对象包含一个url和一个名称。

If I wanted to generate the following HTML for each object:

如果我想为每个对象生成以下HTML:

    <div><img src="the url" />the name</div>

Is there a best practice for this? I can see a few ways of doing it:

有什么最佳实践吗?我可以看到一些方法:

  1. Concatenate strings
  2. 连接字符串
  3. Create elements
  4. 创建元素
  5. Use a templating plugin
  6. 使用一个模板插件
  7. Generate the html on the server, then serve up via JSON.
  8. 在服务器上生成html,然后通过JSON服务。

8 个解决方案

#1


60  

Options #1 and #2 are going to be your most immediate straight forward options, however, for both options, you're going to feel the performance and maintenance impact by either building strings or creating DOM objects.

选项#1和#2将是您最直接的直接向前的选项,但是,对于这两个选项,您将通过构建字符串或创建DOM对象来感受性能和维护的影响。

Templating isn't all that immature, and you're seeing it popup in most of the major Javascript frameworks.

模板化并不是那么不成熟,您可以在大多数主要的Javascript框架中看到它的出现。

Here's an example in JQuery Template Plugin that will save you the performance hit, and is really, really straightforward:

下面是JQuery模板插件中的一个例子,它将为您节省性能冲击,而且非常非常简单:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

I say go the cool route (and better performing, more maintainable), and use templating.

我建议走冷路线(更好的性能,更易于维护),并使用模板。

#2


13  

If you absolutely have to concatenate strings, instead of the normal :

如果你一定要连接字符串,而不是普通的:

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

use a temporary array:

使用一个临时数组:

var s=[];
for (var i=0; i < 200; ++i) { s.push("testing"); }
s = s.join("");

Using arrays is much faster, especially in IE. I did some testing with strings a while ago with IE7, Opera and FF. Opera took only 0.4s to perform the test, but IE7 hadn't finished after 20 MINUTES !!!! ( No, I am not kidding. ) With array IE was very fast.

使用数组要快得多,尤其是在IE中。我在之前做过一些测试,比如IE7, Opera和FF。Opera只用了0.4秒就完成了测试,但是IE7在20分钟后还没有完成!!(不,我不是在开玩笑。)使用数组IE非常快。

#3


8  

Either of the first two options is both common and acceptable.

前两个选项中的任何一个都是通用和可接受的。

I'll give examples of each one in Prototype.

我将在Prototype中给出每个示例。

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

Approach #1:

方法# 1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

Approach #2:

方法# 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom

#4


6  

Here's an example, using my Simple Templates plug-in for jQuery:

下面是一个例子,使用我的jQuery简单模板插件:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);

#5


6  

Perhaps a more modern approach is to use a templating language such as Mustache, which has implementations in many languages, including javascript. For example:

也许更现代的方法是使用一种模板语言,比如Mustache,它在许多语言中都有实现,包括javascript。例如:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

You even get an added benefit - you can reuse the same templates in other places, such as the server side.

您甚至还可以获得额外的好处——您可以在其他地方重用相同的模板,比如服务器端。

If you need more complicated templates (if statements, loops, etc.), you can use Handlebars which has more features, and is compatible with Mustache.

如果您需要更复杂的模板(If语句、循环等),您可以使用有更多特性、与Mustache兼容的Handlebars。

#6


4  

You could add the template HTML to your page in a hidden div and then use cloneNode and your favorite library's querying facilities to populate it

您可以将模板HTML添加到隐藏的div中,然后使用cloneNode和您最喜欢的库的查询功能来填充它

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $$(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})

#7


3  

Disclosure: I am the maintainer of BOB.

信息披露:我是BOB的维护者。

There is a javascript library that makes this process a lot easier called BOB.

For your specific example:

你的具体的例子:

<div><img src="the url" />the name</div>

This can be generated with BOB by the following code.

这可以通过以下代码与BOB一起生成。

new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
//=> "<div><img src="the url" />the name</div>"

Or with the shorter syntax

或者使用更短的语法。

new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
//=> "<div><img src="the url" />the name</div>"

This library is quite powerful and can be used to create very complex structures with data insertion (similar to d3), eg.:

这个库非常强大,可以用数据插入创建非常复杂的结构(类似于d3),例如:

data = [1,2,3,4,5,6,7]
new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
//=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"

BOB does currently not support injecting the data into the DOM. This is on the todolist. For now you can simply use the output together with normal JS, or jQuery, and put it wherever you want.

BOB目前不支持将数据注入DOM。这在待办事项列表中。现在,您可以简单地将输出与普通的JS或jQuery一起使用,并将其放置到任何您想要的位置。

document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
//Or jquery:
$("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());

I made this library because I was not pleased with any of the alternatives like jquery and d3. The code very complicated and hard to read. Working with BOB is in my opinion, which is obviously biased, a lot more pleasant.

我创建了这个库,因为我不喜欢jquery和d3之类的其他选择。代码非常复杂,很难读懂。在我看来,和BOB一起工作显然是有偏见的,要愉快得多。

BOB is available on Bower, so you can get it by running bower install BOB.

BOB在Bower上可用,所以您可以通过运行Bower安装BOB来获得它。

#8


1  

Is there a best practice for this? I can see a few ways of doing it:

有什么最佳实践吗?我可以看到一些方法:

  1. Concatenate strings
  2. 连接字符串
  3. Create elements
  4. 创建元素
  5. Use a templating plugin
  6. 使用一个模板插件
  7. Generate the html on the server, then serve up via JSON.
  8. 在服务器上生成html,然后通过JSON服务。

1) This is an option. Build up the html with JavaScript on the client side and then inject it in the DOM as a whole.

这是一个选项。在客户端用JavaScript构建html,然后将其注入到DOM中。

Note that there is a paradigm behind this approach: the server outputs just data and (in case of interaction) receives data from the client asyncronoulsy with AJAX requests. The client side code operete as a stand-alone JavaScript web application.

注意,这种方法背后有一个范例:服务器只输出数据,(在交互的情况下)用AJAX请求从客户端异步响应接收数据。客户端代码operete是一个独立的JavaScript web应用程序。

The web application may operate, render the interface, even without the server being up (of course it won't display any data or offer any kind of interaction).

web应用程序可以操作、呈现接口,即使服务器没有打开(当然,它不会显示任何数据或提供任何类型的交互)。

This paradigm is getting adopted often lately, and entire frameworks are build around this approach (see backbone.js for example).

这种范式最近经常被采用,整个框架都围绕这种方法构建(参见主干)。例如js)。

2) For performance reasons, when possible, is better to build the html in a string and then inject it as a whole into the page.

2)出于性能原因,如果可能的话,最好将html构建在一个字符串中,然后将其作为一个整体注入到页面中。

3) This is another option, as well as adopting a Web Application framework. Other users have posted various templating engines available. I have the impression that you have the skills to evaluate them and decide whether to follow this path or not.

3)这是另一个选择,以及采用Web应用程序框架。其他用户已经发布了各种可用的模板引擎。我的印象是你有能力评估他们,并决定是否走这条路。

4) Another option. But serve it up as a plain text/html; why JSON? I don't like this approach because mixes PHP (your server language) with Html. But I adopt it often as a reasonable compromise between option 1 and 4.

4)另一种选择。但是作为纯文本/html提供;JSON的原因吗?我不喜欢这种方法,因为将PHP(您的服务器语言)与Html混合在一起。但我经常把它作为选项1和选项4之间的合理妥协。


My answer: you are already looking in the right direction.

我的回答是:你已经找到了正确的方向。

I suggest to adopt an approach between 1 and 4 like I do. Otherwise adopt a web framework or templating engine.

我建议像我一样采用1到4之间的方法。否则采用web框架或模板引擎。

Just my opinion based on my experience...

根据我的经验……

#1


60  

Options #1 and #2 are going to be your most immediate straight forward options, however, for both options, you're going to feel the performance and maintenance impact by either building strings or creating DOM objects.

选项#1和#2将是您最直接的直接向前的选项,但是,对于这两个选项,您将通过构建字符串或创建DOM对象来感受性能和维护的影响。

Templating isn't all that immature, and you're seeing it popup in most of the major Javascript frameworks.

模板化并不是那么不成熟,您可以在大多数主要的Javascript框架中看到它的出现。

Here's an example in JQuery Template Plugin that will save you the performance hit, and is really, really straightforward:

下面是JQuery模板插件中的一个例子,它将为您节省性能冲击,而且非常非常简单:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

I say go the cool route (and better performing, more maintainable), and use templating.

我建议走冷路线(更好的性能,更易于维护),并使用模板。

#2


13  

If you absolutely have to concatenate strings, instead of the normal :

如果你一定要连接字符串,而不是普通的:

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

use a temporary array:

使用一个临时数组:

var s=[];
for (var i=0; i < 200; ++i) { s.push("testing"); }
s = s.join("");

Using arrays is much faster, especially in IE. I did some testing with strings a while ago with IE7, Opera and FF. Opera took only 0.4s to perform the test, but IE7 hadn't finished after 20 MINUTES !!!! ( No, I am not kidding. ) With array IE was very fast.

使用数组要快得多,尤其是在IE中。我在之前做过一些测试,比如IE7, Opera和FF。Opera只用了0.4秒就完成了测试,但是IE7在20分钟后还没有完成!!(不,我不是在开玩笑。)使用数组IE非常快。

#3


8  

Either of the first two options is both common and acceptable.

前两个选项中的任何一个都是通用和可接受的。

I'll give examples of each one in Prototype.

我将在Prototype中给出每个示例。

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

Approach #1:

方法# 1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

Approach #2:

方法# 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom

#4


6  

Here's an example, using my Simple Templates plug-in for jQuery:

下面是一个例子,使用我的jQuery简单模板插件:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);

#5


6  

Perhaps a more modern approach is to use a templating language such as Mustache, which has implementations in many languages, including javascript. For example:

也许更现代的方法是使用一种模板语言,比如Mustache,它在许多语言中都有实现,包括javascript。例如:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

You even get an added benefit - you can reuse the same templates in other places, such as the server side.

您甚至还可以获得额外的好处——您可以在其他地方重用相同的模板,比如服务器端。

If you need more complicated templates (if statements, loops, etc.), you can use Handlebars which has more features, and is compatible with Mustache.

如果您需要更复杂的模板(If语句、循环等),您可以使用有更多特性、与Mustache兼容的Handlebars。

#6


4  

You could add the template HTML to your page in a hidden div and then use cloneNode and your favorite library's querying facilities to populate it

您可以将模板HTML添加到隐藏的div中,然后使用cloneNode和您最喜欢的库的查询功能来填充它

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $$(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})

#7


3  

Disclosure: I am the maintainer of BOB.

信息披露:我是BOB的维护者。

There is a javascript library that makes this process a lot easier called BOB.

For your specific example:

你的具体的例子:

<div><img src="the url" />the name</div>

This can be generated with BOB by the following code.

这可以通过以下代码与BOB一起生成。

new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
//=> "<div><img src="the url" />the name</div>"

Or with the shorter syntax

或者使用更短的语法。

new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
//=> "<div><img src="the url" />the name</div>"

This library is quite powerful and can be used to create very complex structures with data insertion (similar to d3), eg.:

这个库非常强大,可以用数据插入创建非常复杂的结构(类似于d3),例如:

data = [1,2,3,4,5,6,7]
new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
//=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"

BOB does currently not support injecting the data into the DOM. This is on the todolist. For now you can simply use the output together with normal JS, or jQuery, and put it wherever you want.

BOB目前不支持将数据注入DOM。这在待办事项列表中。现在,您可以简单地将输出与普通的JS或jQuery一起使用,并将其放置到任何您想要的位置。

document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
//Or jquery:
$("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());

I made this library because I was not pleased with any of the alternatives like jquery and d3. The code very complicated and hard to read. Working with BOB is in my opinion, which is obviously biased, a lot more pleasant.

我创建了这个库,因为我不喜欢jquery和d3之类的其他选择。代码非常复杂,很难读懂。在我看来,和BOB一起工作显然是有偏见的,要愉快得多。

BOB is available on Bower, so you can get it by running bower install BOB.

BOB在Bower上可用,所以您可以通过运行Bower安装BOB来获得它。

#8


1  

Is there a best practice for this? I can see a few ways of doing it:

有什么最佳实践吗?我可以看到一些方法:

  1. Concatenate strings
  2. 连接字符串
  3. Create elements
  4. 创建元素
  5. Use a templating plugin
  6. 使用一个模板插件
  7. Generate the html on the server, then serve up via JSON.
  8. 在服务器上生成html,然后通过JSON服务。

1) This is an option. Build up the html with JavaScript on the client side and then inject it in the DOM as a whole.

这是一个选项。在客户端用JavaScript构建html,然后将其注入到DOM中。

Note that there is a paradigm behind this approach: the server outputs just data and (in case of interaction) receives data from the client asyncronoulsy with AJAX requests. The client side code operete as a stand-alone JavaScript web application.

注意,这种方法背后有一个范例:服务器只输出数据,(在交互的情况下)用AJAX请求从客户端异步响应接收数据。客户端代码operete是一个独立的JavaScript web应用程序。

The web application may operate, render the interface, even without the server being up (of course it won't display any data or offer any kind of interaction).

web应用程序可以操作、呈现接口,即使服务器没有打开(当然,它不会显示任何数据或提供任何类型的交互)。

This paradigm is getting adopted often lately, and entire frameworks are build around this approach (see backbone.js for example).

这种范式最近经常被采用,整个框架都围绕这种方法构建(参见主干)。例如js)。

2) For performance reasons, when possible, is better to build the html in a string and then inject it as a whole into the page.

2)出于性能原因,如果可能的话,最好将html构建在一个字符串中,然后将其作为一个整体注入到页面中。

3) This is another option, as well as adopting a Web Application framework. Other users have posted various templating engines available. I have the impression that you have the skills to evaluate them and decide whether to follow this path or not.

3)这是另一个选择,以及采用Web应用程序框架。其他用户已经发布了各种可用的模板引擎。我的印象是你有能力评估他们,并决定是否走这条路。

4) Another option. But serve it up as a plain text/html; why JSON? I don't like this approach because mixes PHP (your server language) with Html. But I adopt it often as a reasonable compromise between option 1 and 4.

4)另一种选择。但是作为纯文本/html提供;JSON的原因吗?我不喜欢这种方法,因为将PHP(您的服务器语言)与Html混合在一起。但我经常把它作为选项1和选项4之间的合理妥协。


My answer: you are already looking in the right direction.

我的回答是:你已经找到了正确的方向。

I suggest to adopt an approach between 1 and 4 like I do. Otherwise adopt a web framework or templating engine.

我建议像我一样采用1到4之间的方法。否则采用web框架或模板引擎。

Just my opinion based on my experience...

根据我的经验……