簡體   English   中英

是否有使用javascript生成html的最佳實踐

[英]Is there a best practice for generating html with javascript

我正在調用一個Web服務,它返回JSON中的對象數組。 我想獲取這些對象並使用HTML填充div。 假設每個對象都包含一個url和一個名稱。

如果我想為每個對象生成以下HTML:

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

這是最好的做法嗎? 我可以看到幾種方法:

  1. 連接字符串
  2. 創建元素
  3. 使用模板插件
  4. 在服務器上生成html,然后通過JSON提供。

選項#1和#2將是您最直接的選擇,但是,對於這兩個選項,您將通過構建字符串或創建DOM對象來感受性能和維護的影響。

模板化並不是那么不成熟,你會在大多數主要的Javascript框架中看到它彈出。

這是JQuery模板插件中的一個示例,可以為您節省性能,實際上非常簡單:

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

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

我說走酷路線(更好的表現,更易於維護),並使用模板。

如果你絕對必須連接字符串,而不是正常的:

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做了一些字符串測試。 Opera只用了0.4秒就完成了測試,但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

也許更現代的方法是使用模仿語言,例如Mustache ,它具有多種語言的實現,包括javascript。 例如:

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

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

您甚至可以獲得額外的好處 - 您可以在其他位置重用相同的模板,例如服務器端。

如果您需要更復雜的模板(如果語句,循環等),您可以使用具有更多功能並與Mustache兼容的Handlebars

這是一個例子,使用我的簡單模板插件為jQuery:

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

您可以在隱藏的div中將模板HTML添加到頁面中,然后使用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>"

這個庫非常強大,可用於創建非常復雜的數據插入結構(類似於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等任何替代品都不滿意。 代碼非常復雜,難以閱讀。 在我看來,與BOB合作顯然有偏見,更令人愉快。

BOB可以在Bower上使用 ,所以你可以通過運行bower install BOB來獲得它。

這是最好的做法嗎? 我可以看到幾種方法:

  1. 連接字符串
  2. 創建元素
  3. 使用模板插件
  4. 在服務器上生成html,然后通過JSON提供。

1)這是一個選項。 在客戶端使用JavaScript構建html,然后將其作為一個整體注入到DOM中。

請注意,這種方法背后有一個范例:服務器僅輸出數據,並且(在交互的情況下)從客戶端接收數據與AJAX請求異步。 客戶端代碼作為獨立的JavaScript Web應用程序運行。

即使沒有服務器啟動,Web應用程序也可以操作,呈現界面(當然它不會顯示任何數據或提供任何類型的交互)。

這個范例最近經常被采用,並且整個框架都是圍繞這種方法構建的(例如,參見backbone.js)。

2)出於性能原因,在可能的情況下,最好在字符串中構建html,然后將其作為一個整體注入頁面。

3)這是另一種選擇,也是采用Web應用程序框架。 其他用戶已經發布了各種模板引擎。 我的印象是你有能力評估它們並決定是否遵循這條道路。

4)另一種選擇。 但是把它作為純文本/ html提供; 為什么JSON? 我不喜歡這種方法,因為將PHP(您的服務器語言)與Html混合在一起。 但我經常采用它作為選項14之間的合理折衷方案。


我的回答:你已經在尋找正確的方向。

我建議像我一樣采用14之間的方法。 否則采用Web框架或模板引擎。

根據我的經驗,我的意見......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM