JavaScript ile html oluşturmak için bir en iyi uygulama var mı


103

JSON'da bir dizi nesne döndüren bir web hizmetini arıyorum. Bu nesneleri alıp HTML ile bir div oluşturmak istiyorum. Her nesnenin bir url ve bir ad içerdiğini varsayalım.

Her nesne için aşağıdaki HTML'yi oluşturmak istersem:

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

Bunun için bir en iyi uygulama var mı? Bunu yapmanın birkaç yolunu görebiliyorum:

  1. Dizeleri birleştir
  2. Öğeler oluşturun
  3. Şablon eklentisi kullanın
  4. Sunucuda html'yi oluşturun, ardından JSON aracılığıyla sunun.

1
Ayrıca alt çizgi
js'yi

1-4 mong seçimi: ne kadar içeriğin enjekte edileceğine bağlıdır. (Daha büyük için 4'ü tercih edin) toplamda kaç farklı html parçasının eklenmesi gerekeceği (3 veya 4). sb'nin aşina olduğu. (Geliştirme süresindeki etki). Eğer herhangi bir araç bilmiyorsanız, bu sadece küçük bir modal, bunu yapmak için saf js'den daha iyi bir yol bilmediğimde enjekte edilecek (1-2)
partizanos

Yanıtlar:


68

Seçenekler # 1 ve # 2, en acil ve basit seçenekleriniz olacak, ancak her iki seçenek için de dizeler oluşturarak veya DOM nesneleri oluşturarak performans ve bakım etkisini hissedeceksiniz.

Şablon oluşturma o kadar da olgunlaşmamış değil ve büyük Javascript çerçevelerinin çoğunda açılır pencereyi görüyorsunuz.

İşte JQuery Şablon Eklentisinde sizi performans artışından kurtaracak ve gerçekten çok basit olan bir örnek:

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

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

Harika rotaya gidin (ve daha iyi performans gösteren, daha sürdürülebilir) ve şablonlama kullanın derim.


13
JQuery şablonlama ölmüş gibi görünüyor, bkz. Stackoverflow.com/questions/7911732/…
James McMahon

4
@Jim Fiorato: bağlantı öldü: s
Adrien Be

2
Adrien'in belirttiği gibi bağlantı öldü. Eklemek cevap güncellemek önerin: Mustache.js
Sn Polywhirl

1
Birisi lütfen açıklayabilir mi, jQuery tabanlı bir yanıt neden kabul edildi? Bunun en iyi uygulama olduğundan şüpheliyim!
2016

1
@WoIIe Daha da kötüsü, jQuery eklentisi öldü, bu yüzden bu yanıt güncel değil.
Franklin Yu

13

Normal yerine dizeleri kesinlikle birleştirmeniz gerekiyorsa:

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

geçici bir dizi kullanın:

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

Dizi kullanmak, özellikle IE'de çok daha hızlıdır. Bir süre önce IE7, Opera ve FF ile dizelerle bazı testler yaptım. Opera testi gerçekleştirmek için yalnızca 0,4 saniye sürdü, ancak IE7 20 DAKİKA sonra bitirmemişti !!!! (Hayır, şaka yapmıyorum.) Dizi ile IE çok hızlıydı.


Tarayıcıyı uzun zaman önce değiştirdim, bu yüzden o kadar acı çekmiyorum. IE korkunç bir tarayıcıydı ama giderek daha iyi hale geliyor. Ama geri döneceğimden şüpheliyim.
bazı

1
İlk yöntemde görülen yavaş performans büyük olasılıkla sonuç dizesinin 200 kez yeniden tahsis edilmesi gerektiğinden ve bellek ayırmalarının yavaş olmasından kaynaklanmaktadır. İki yinelemeden sonra "test testine" sahip olursunuz. Üç yinelemeden sonra, bu dizi atılır ve "test testi testi" için yeterli alana sahip bellek ayrılır. Ve böylece, giderek artan uzunlukta 200 kez. Ancak s.join (), sonuç olarak hepsine sığacak kadar uzun bir yeni dize ayırır ve ardından her birine kopyalar. Tek tahsis, çok daha hızlı.
EricP

1
@JoeCoder, onun bir Shlemiel The Painter algoritması olduğunu kabul etti. joelonsoftware.com/articles/fog0000000319.html
Jodrell

8

İlk iki seçenekten biri hem yaygın hem de kabul edilebilir.

Prototip'te her biri için örnekler vereceğim .

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

Yaklaşım 1:

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

Yaklaşım # 2:

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

HTML'yi DOM öğelerinden ziyade dizelerle açıkça oluşturmak daha performanslı (dize birleştirme gerçek bir sorun olmadığı varsayılırsa) ve okunabilirdir.
Rodrick Chapman

IE'de dize birleştirme her zaman bir sorundur. Bunun yerine bir dizi kullanın.
bazı

7

Belki daha modern bir yaklaşım gibi bir şablon dili kullanmaktır Bıyık javascript dahil olmak üzere birçok dilde uygulamaları bulunmaktadır. Örneğin:

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

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

Hatta ek bir avantaj elde edersiniz - aynı şablonları sunucu tarafı gibi başka yerlerde yeniden kullanabilirsiniz.

(İfadeler, döngüler, vb ise), kullanabilirsiniz daha karmaşık şablonlar gerekiyorsa Gidonu fazla özellik vardır ve Bıyık ile uyumlu olan.


6

JQuery için Simple Templates eklentimi kullanan bir örnek :

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

1
Düzgün. Birkaç ay önce büyük bir projede buna benzer bir şey kullanabilirdim.
Rodrick Chapman

Evet. Özlü ve temiz!
ajitweb

4

Şablon HTML'yi sayfanıza gizli bir div'de ekleyebilir ve ardından onu doldurmak için cloneNode'u ve en sevdiğiniz kitaplığın sorgulama olanaklarını kullanabilirsiniz.

/* 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*/})

3

Açıklama: BOB'un geliştiricisiyim.

Bu işlemi çok daha kolay hale getiren BOB adı verilen bir javascript kütüphanesi var .

Size özel örnek için:

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

Bu, aşağıdaki kodla BOB ile oluşturulabilir.

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

Veya daha kısa sözdizimiyle

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

Bu kütüphane oldukça güçlüdür ve veri ekleme (d3'e benzer) ile çok karmaşık yapılar oluşturmak için kullanılabilir, örn .:

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 şu anda verilerin DOM'a enjekte edilmesini desteklemiyor. Bu todolist'te. Şimdilik, çıktıyı normal JS veya jQuery ile birlikte kullanabilir ve istediğiniz yere koyabilirsiniz.

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());

Bu kütüphaneyi jquery ve d3 gibi alternatiflerin hiçbirinden memnun olmadığım için yaptım. Kod çok karmaşık ve okunması zor. BOB ile çalışmak bence, açıkçası önyargılı, çok daha keyifli.

BOB geçerli Bower çalıştırmakta bunu alabilmesi için, bower install BOB.


2

Bunun için bir en iyi uygulama var mı? Bunu yapmanın birkaç yolunu görebiliyorum:

  1. Dizeleri birleştir
  2. Öğeler oluşturun
  3. Şablon eklentisi kullanın
  4. Sunucuda html'yi oluşturun, ardından JSON aracılığıyla sunun.

1) Bu bir seçenektir. İstemci tarafında JavaScript ile html'yi oluşturun ve ardından DOM'a bir bütün olarak enjekte edin.

Bu yaklaşımın arkasında bir paradigma olduğuna dikkat edin: sunucu yalnızca veri çıkarır ve (etkileşim durumunda), AJAX talepleriyle birlikte istemciden eşzamansız veri alır. İstemci tarafı kodu, bağımsız bir JavaScript web uygulaması olarak çalışır.

Web uygulaması, sunucu açıkken bile çalışabilir, arayüzü oluşturabilir (tabii ki herhangi bir veri göstermez veya herhangi bir etkileşim sunmaz).

Bu paradigma son zamanlarda sıklıkla benimseniyor ve tüm çerçeveler bu yaklaşım etrafında inşa ediliyor (örneğin, backbone.js'ye bakın).

2) Performans nedenlerinden ötürü, mümkün olduğunda, html'yi bir dizede oluşturmak ve sonra onu bir bütün olarak sayfaya enjekte etmek daha iyidir.

3) Bu, bir Web Uygulaması çerçevesi benimsemenin yanı sıra başka bir seçenektir. Diğer kullanıcılar çeşitli şablon oluşturma motorları yayınladılar. Onları değerlendirme ve bu yolu takip edip etmeme konusunda karar verme becerisine sahip olduğunuz izlenimini edindim.

4) Başka bir seçenek. Ancak bunu düz metin / html olarak sunun; neden JSON? Bu yaklaşımı sevmiyorum çünkü PHP'yi (sunucu diliniz) Html ile karıştırıyor. Ancak bunu genellikle 1. ve 4. seçenek arasında makul bir uzlaşma olarak kabul ediyorum .


Cevabım: zaten doğru yöne bakıyorsun.

Benim yaptığım gibi 1 ile 4 arasında bir yaklaşım benimsemeyi öneririm . Aksi takdirde bir web çerçevesi veya şablon oluşturma motoru kullanın.

Sadece deneyimlerime dayanan fikrim ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.