有没有一个最佳做法,生成与JavaScript的HTML

我正在调用一个Web服务,返回JSON中的对象数组。 我想采取这些对象,并用HTML填充一个div。 假设每个对象都包含一个url和一个名字。

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

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

有这个最好的做法吗? 我可以看到一些做法:

  1. 连接string
  2. 创build元素
  3. 使用模板插件
  4. 在服务器上生成html,然后通过JSON提供。

选项#1和#2将成为您最直接的直接选项,但是,对于这两种选项,您都将通过构buildstring或创buildDOM对象来感受性能和维护的影响。

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

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

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

我说走酷路线(和更好的performance,更可维护),并使用模板。

如果你绝对必须连接string,而不是正常的:

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

使用临时数组:

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

使用数组要快得多,特别是在IE中。 我不久前用IE7,Opera和FF做了一些testing。 Opera只用了0.4秒来完成testing,但IE7在20分钟后还没有完成! (不,我不是在开玩笑。)与数组IE非常快。

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

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

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

方法1:

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

方法2:

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

下面是一个例子,使用jQuery的Simple Templates插件:

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

也许更现代的方法是使用模板语言,如Mustache ,其中包括JavaScript在内的多种语言的实现。 例如:

 var view = { url: "/hello", name: function () { return 'Jo' + 'hn'; } }; var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view); 

您甚至可以获得额外的好处 – 您可以在其他地方(如服务器端)重复使用相同的模板。

如果您需要更复杂的模板(如语句,循环等),则可以使用具有更多function的把手 ,并与小胡子兼容。

你可以添加模板的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*/}) 

披露:我是BOB的维护者。

有一个JavaScript库,使这个过程更容易称为BOB 。

对于你的具体例子:

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

这可以由BOB通过以下代码生成。

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

或者用更短的语法

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

这个库是非常强大的,可以用来创build非常复杂的结构与数据插入(类似于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目前不支持将数据注入到DOM中。 这是todolist。 现在,您可以简单地将输出与普通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()); 

我做了这个库,因为我不喜欢任何像jQuery和D3的select。 代码非常复杂,难以阅读。 在我看来,与BOB工作显然是有偏见的,更加愉快。

BOB在Bower上可用,所以你可以通过运行bower install BOB来获得它。

有这个最好的做法吗? 我可以看到一些做法:

  1. 连接string
  2. 创build元素
  3. 使用模板插件
  4. 在服务器上生成html,然后通过JSON提供。

1)这是一个选项。 在客户端使用JavaScript构buildhtml,然后将其作为一个整体注入到DOM中。

请注意,这种方法背后有一个范例:服务器只输出数据,(在交互的情况下)通过AJAX请求从客户端接收asynchronous数据。 客户端代码作为独立的JavaScript Web应用程序进行操作。

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

这种模式最近经常被采用,整个框架都围绕着这种方法(例如,参见backbone.js)。

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

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

4)另一种select。 但是将其作为纯文本/ html提供; 为什么selectJSON? 我不喜欢这种方法,因为混合PHP(你的服务器语言)与Html。 但我经常把它作为选项14之间的合理折衷。


我的回答:你已经在正确的方向看。

我build议像我一样采用14的方法。 否则采用一个web框架或模板引擎。

只是我的意见根据我的经验…