有没有一个最佳做法,生成与JavaScript的HTML
我正在调用一个Web服务,返回JSON中的对象数组。 我想采取这些对象,并用HTML填充一个div。 假设每个对象都包含一个url和一个名字。
如果我想为每个对象生成以下HTML:
<div><img src="the url" />the name</div>
有这个最好的做法吗? 我可以看到一些做法:
- 连接string
- 创build元素
- 使用模板插件
- 在服务器上生成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
来获得它。
有这个最好的做法吗? 我可以看到一些做法:
- 连接string
- 创build元素
- 使用模板插件
- 在服务器上生成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。 但我经常把它作为选项1和4之间的合理折衷。
我的回答:你已经在正确的方向看。
我build议像我一样采用1到4的方法。 否则采用一个web框架或模板引擎。
只是我的意见根据我的经验…