Apakah ada praktik terbaik untuk membuat html dengan javascript

103

Saya memanggil layanan web yang mengembalikan larik objek di JSON. Saya ingin mengambil objek tersebut dan mengisi div dengan HTML. Katakanlah setiap objek berisi url dan nama.

Jika saya ingin membuat HTML berikut untuk setiap objek:

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

Apakah ada praktik terbaik untuk ini? Saya dapat melihat beberapa cara untuk melakukannya:

  1. String gabungan
  2. Buat elemen
  3. Gunakan plugin template
  4. Hasilkan html di server, lalu sajikan melalui JSON.
ckarbass.dll
sumber
1
Anda juga dapat memeriksa garis bawah js: documentcloud.github.com/underscore/#template Ini
berfungsi
Pilihan mong 1-4: tergantung pada berapa banyak konten yang akan disuntikkan. (Pilih 4 untuk yang lebih besar) berapa banyak bagian html yang berbeda yang perlu ditambahkan secara total (3 atau 4). apa yang sb kenal. (Pengaruh dalam waktu dev). Jika Anda tidak tahu alat apa pun, itu hanya modal kecil yang akan disuntikkan setelah saya tidak tahu cara yang lebih baik daripada js murni untuk melakukannya (1-2)
partizanos

Jawaban:

68

Opsi # 1 dan # 2 akan menjadi opsi langsung paling cepat Anda, namun, untuk kedua opsi tersebut, Anda akan merasakan dampak kinerja dan pemeliharaan dengan membuat string atau membuat objek DOM.

Templating tidak terlalu dewasa, dan Anda melihatnya muncul di sebagian besar kerangka Javascript utama.

Berikut adalah contoh dalam JQuery Template Plugin yang akan menghemat kinerja Anda, dan sangat, sangat mudah:

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

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

Saya katakan ikuti rute yang keren (dan berkinerja lebih baik, lebih mudah dirawat), dan gunakan template.

Jim Fiorato
sumber
13
JQuery templating tampaknya mati, lihat stackoverflow.com/questions/7911732/…
James McMahon
4
@Jim Fiorato: tautannya mati: s
Adrien Be
2
Link sudah mati, seperti yang ditunjukkan Adrien. Sarankan Anda memperbarui jawaban Anda untuk menyertakan: Moustache.js
Mr. Polywhirl
1
Bisakah seseorang menjelaskan, mengapa jawaban berbasis jQuery diterima? Saya ragu ini adalah praktik terbaik!
WoIIe
1
@WoIIe Lebih buruk lagi, plugin jQuery sudah mati, jadi jawaban ini sudah ketinggalan zaman.
Franklin Yu
13

Jika Anda benar-benar harus menggabungkan string, bukan yang normal:

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

gunakan array sementara:

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

Menggunakan array jauh lebih cepat, terutama di IE. Saya melakukan beberapa pengujian dengan string beberapa waktu lalu dengan IE7, Opera dan FF. Opera hanya membutuhkan 0,4 detik untuk melakukan tes, tetapi IE7 belum selesai setelah 20 MENIT !!!! (Tidak, saya tidak bercanda.) Dengan array IE sangat cepat.

beberapa
sumber
Saya sudah lama berganti browser, jadi saya tidak terlalu menderita. IE adalah browser yang mengerikan tetapi semakin baik. Tapi saya ragu saya akan beralih kembali.
sekitar
1
Performa lambat yang terlihat pada metode pertama kemungkinan besar karena string hasil harus dialokasikan ulang 200 kali, dan alokasi memori bisa lambat. Setelah dua iterasi, Anda memiliki "testingtesting". Setelah tiga iterasi, string tersebut dibuang dan memori dengan ruang yang cukup untuk "testingtestingtesting" dialokasikan. Dan seterusnya 200 kali dengan panjang yang bertambah secara bertahap. Namun s.join () mengalokasikan satu string baru sebagai hasil yang cukup panjang untuk memuat semuanya, lalu menyalin di masing-masing. Satu alokasi, lebih cepat.
EricP
1
@JoeCoder, setuju, ini adalah algoritma Shlemiel The Painter. joelonsoftware.com/articles/fog0000000319.html
Jodrell
8

Salah satu dari dua opsi pertama adalah umum dan dapat diterima.

Saya akan memberikan contoh masing-masing di Prototype .

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

Pendekatan # 1:

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

Pendekatan # 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom
menyelamatkan menara jam
sumber
Membangun pembuatan HTML secara eksplisit dengan string daripada elemen DOM lebih berkinerja (dengan asumsi penggabungan string bukanlah masalah nyata) dan dapat dibaca.
Rodrick Chapman
Dalam penggabungan string IE selalu menjadi masalah. Gunakan array sebagai gantinya.
beberapa
7

Mungkin pendekatan yang lebih modern adalah dengan menggunakan bahasa template seperti Mustache , yang memiliki implementasi dalam banyak bahasa, termasuk javascript. Sebagai contoh:

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

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

Anda bahkan mendapatkan keuntungan tambahan - Anda dapat menggunakan kembali template yang sama di tempat lain, seperti sisi server.

Jika Anda membutuhkan templat yang lebih rumit (jika pernyataan, loop, dll.), Anda dapat menggunakan Handlebars yang memiliki lebih banyak fitur, dan kompatibel dengan Mustache.

Tzach
sumber
6

Berikut adalah contohnya, menggunakan plugin Simple Templates saya untuk jQuery:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);
Andrew Hedges
sumber
1
Rapi. Saya bisa saja menggunakan sesuatu yang seperti itu pada proyek besar beberapa bulan lalu.
Rodrick Chapman
Iya. Ringkas dan rapi!
ajitweb
4

Anda dapat menambahkan template HTML ke halaman Anda dalam div tersembunyi dan kemudian menggunakan cloneNode dan fasilitas kueri perpustakaan favorit Anda untuk mengisinya

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

Pengungkapan: Saya adalah pengelola BOB.

Ada pustaka javascript yang membuat proses ini jauh lebih mudah disebut BOB .

Untuk contoh spesifik Anda:

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

Ini dapat dibuat dengan BOB dengan kode berikut.

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

Atau dengan sintaks yang lebih pendek

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

Perpustakaan ini cukup kuat dan dapat digunakan untuk membuat struktur yang sangat kompleks dengan penyisipan data (mirip dengan d3), misalnya:

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 saat ini tidak mendukung penyuntikan data ke DOM. Ini di todolist. Untuk saat ini Anda cukup menggunakan output bersama dengan JS normal, atau jQuery, dan meletakkannya di mana pun Anda inginkan.

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

Saya membuat perpustakaan ini karena saya tidak senang dengan alternatif seperti jquery dan d3. Kode tersebut sangat rumit dan sulit dibaca. Bekerja dengan BOB menurut saya, yang jelas bias, jauh lebih menyenangkan.

BOB tersedia di Bower , jadi Anda bisa mendapatkannya dengan menjalankannya bower install BOB.

Automatico
sumber
2

Apakah ada praktik terbaik untuk ini? Saya dapat melihat beberapa cara untuk melakukannya:

  1. String gabungan
  2. Buat elemen
  3. Gunakan plugin template
  4. Hasilkan html di server, lalu sajikan melalui JSON.

1) Ini adalah opsi. Bangun html dengan JavaScript di sisi klien dan kemudian masukkan ke dalam DOM secara keseluruhan.

Perhatikan bahwa ada paradigma di balik pendekatan ini: server hanya mengeluarkan data dan (dalam kasus interaksi) menerima data dari klien asyncronoulsy dengan permintaan AJAX. Kode sisi klien beroperasi sebagai aplikasi web JavaScript yang berdiri sendiri.

Aplikasi web dapat beroperasi, membuat antarmuka, bahkan tanpa server aktif (tentu saja itu tidak akan menampilkan data apa pun atau menawarkan interaksi apa pun).

Paradigma ini sering diadopsi akhir-akhir ini, dan seluruh kerangka kerja dibangun berdasarkan pendekatan ini (lihat backbone.js misalnya).

2) Untuk alasan kinerja, jika memungkinkan, lebih baik untuk membangun html dalam sebuah string dan kemudian memasukkannya secara keseluruhan ke dalam halaman.

3) Ini adalah opsi lain, serta mengadopsi kerangka Aplikasi Web. Pengguna lain telah memposting berbagai mesin template yang tersedia. Saya mendapat kesan bahwa Anda memiliki keterampilan untuk mengevaluasinya dan memutuskan apakah akan mengikuti jalan ini atau tidak.

4) Pilihan lain. Tapi sajikan sebagai teks biasa / html; kenapa JSON? Saya tidak suka pendekatan ini karena mencampurkan PHP (bahasa server Anda) dengan Html. Tetapi saya sering mengadopsinya sebagai kompromi yang masuk akal antara opsi 1 dan 4 .


Jawaban saya: Anda sudah melihat ke arah yang benar.

Saya menyarankan untuk mengadopsi pendekatan antara 1 dan 4 seperti yang saya lakukan. Jika tidak, gunakan kerangka kerja web atau mesin templat.

Hanya pendapat saya berdasarkan pengalaman saya ...

Paolo
sumber