2010-02-07 15 views
48

jQuery'de biraz karmaşık HTML öğeleri oluşturmak için genel en iyi uygulama var mı? Birkaç farklı yol denedim. appendTo her şey başka türlü kendi ismini o uçları ihtiyacı böylece eşleşen her elemana eklemek istiyor berijQuery - Karmaşık HTML Fragmanları Oluşturmaya Yönelik En İyi Uygulama

var badge = $(document.createElement("div")).attr("class", "wrapper1").appendTo("body"); 
$(document.createElement("div")).attr("class", "wrapper2").appendTo(".wrapper1"); 
$(document.createElement("table")).attr("class", "badgeBody").appendTo(".wrapper2"); 
$(document.createElement("tr")).attr("class", "row1").appendTo(".badgeBody"); 
$(document.createElement("td")).appendTo(".row1"); 
$(document.createElement("span")).attr("class", "badgeUnlocked").text("UNLOCKED! ").appendTo("td"); 
$(document.createElement("td")).attr("class", "badgeTitleText").appendTo(".row1"); 
$(document.createElement("span")).attr("class", "badgeTitle").text(name).appendTo(".badgeTitleText"); 
$(document.createElement("tr")).attr("class", "row2").appendTo(".badgeBody"); 
$(document.createElement("td")).appendTo(".row2"); 
$(document.createElement("img")).attr("src", imgUrl).appendTo(".row2 td"); 
$(document.createElement("td")).attr("class", "badgeText").appendTo(".row2"); 
$(document.createElement("span")).attr("class", "badgeDescription").text(description).appendTo(".badgeText"); 

Bu kaba olabilir:

Önce createElement ve birlikte olanların sürü zincirleme AppendTo ile ve benzeri çalıştı her yerde tekrar tekrar yer almaya başladı. IE'de I ($ (badgeFragment) .text()) genellikle bir uyarı koymak ne zaman olmasına rağmen,

var badgeFragment = [ 
'<div><div id="'+ closeId+'" class="closeTab">X</div>', 
'<div id="'+ badgeId+'" class="wrapper1">', 
'<div class="wrapper2">', 
'<div class="badgeBody">', 
'<div class="badgeImage">', 
'<img src="'+ imgUrl +'">', 
'</div>', 
'<div class="badgeContents">', 
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>', 
'<div class="badgeTitle">'+ name +'</div>', 
'<div id="'+ textId+'" class="badgeDescription">'+ description +'</div>', 
'</div>', 
'<div style="clear:both"></div>', 
'</div></div></div></div></div>', 
] 

badgeFragment = $(badgeFragment.join('')); 

Bu oldukça iyi iş gibi görünüyor:

Sonra bir dizi oluşturma ve birlikte katılmadan çalıştı boş geri döndü. (Bu daha büyük bir sorunun hatalarını ayıklamanın bir parçasıydı).

var badgeFragment = 
'<div><div id="'+ closeId+'" class="closeTab">X</div>' + 
'<div id="'+ badgeId+'" class="wrapper1">' + 
'<div class="wrapper2">' + 
'<div class="badgeBody">' + 
'<div class="badgeImage">' + 
'<img src="C:/Users/Ryan/Documents/icons/crystal_project/64x64/apps/chat.png">' + 
'</div>' + 
'<div class="badgeContents">' + 
'<div class="badgeUnlocked">ACHIEVEMENT UNLOCKED: </div>' + 
'<div class="badgeTitle">test</div>' + 
'<div id="'+ textId+'" class="badgeDescription">test</div>' + 
'</div>' + 
'<div style="clear:both"></div>' + 
'</div></div></div></div></div>'; 

genellikle bu yöntemlerden biridir: Dev dize birleştirme - Öyle denemek ve bu üçüncü yöntemi denedik sorun değildi emin olmak için açıkçası jQuery (Ve hatta JavaScript gerçekten) biraz yeniyim Diğerlerinden daha iyi sayılır mı? Çeşitli profilleyicilerle pek iyi değilim, bu yüzden kendimi nasıl doğrulayacağımı bilmiyorum. Tüm bu yöntemlerin çapraz tarayıcı uyumlu olup olmadığı sorusu da vardır.

+0

IE Alert'ünüz çünkü ".text()" DOM ​​alt ağacının tüm içeriğini almaz boş geldi. $ (BadgeFragment) .html() – Pointy

cevap

56

gibi jquery için şablon motorlarından biri bakmak eğimli olurdu, bunu gibi HTML öğelerini oluşturabilirsiniz:

// create an element with an object literal, defining properties 
var e = $("<a />", { 
    href: "#", 
    "class": "a-class another-class", // you need to quote "class" since it's a reserved keyword 
    title: "..." 
}); 

// add the element to the body 
$("body").append(e); 

İşte a link to the documentation bu.

Bu yaklaşımın jQuery öğesinin html() işlevini kullanmasından daha hızlı olduğundan emin değilim. Ya da jQuery'yi hep birlikte atlamaktan daha hızlıdır ve bir öğedeki innerHTML özelliğini kullanın. Fakat okunabilirlik kadar uzağa gider; jQuery yaklaşımı benim favorim. Ve çoğu durumda, innerHTML kullanmanın performans artışı marjinaldir.

+1

jQuery'nin ilk argümanından sonra bir virgül kaçırdınız ($). – Spidey

+1

Teşekkürler Spidey. Cevap güncellendi. [JQuery docs] 'a bağlı olarak – roosteronacid

+1

@roosteronacid (http://api.jquery.com/jQuery/) 'Javascript olarak ayrılmış bir kelime olduğu için" sınıf "adı, nesne içerisinde alıntılanmalıdır. – Pierre

3

Kişisel olarak, kodun performanstan daha okunabilir ve düzenlenebilir olmasının daha önemli olduğunu düşünüyorum. Hangisini daha kolay bulursanız olun ve onu bozmadan değişiklik yapabilirsiniz.

8

Sen document.createElement aramak gerekmez:

/uzanan DOM ammending için jQuery yararlı araçlar her türlü vardır
$('#existingContainer').append(
    $('<div/>') 
    .attr("id", "newDiv1") 
    .addClass("newDiv purple bloated") 
    .append("<span/>") 
     .text("hello world") 
); 

. Örneğin çeşitli "sarma" yöntemlerine bakın.

Başka bir olasılık: gerçekten çok sayıda yeni içerik bloğu için, sunucunuzun bunları hazırlamanız (sunucu tarafında şablonlama sistemini kullanarak, sizin için her neyse) ve $.load() veya başka bir ajax yaklaşımıyla karşılaşmanız daha iyi olabilir. .

8

jQuery 1.4 ile jQote

+1

+ 1'i deneyin. ya da jsRender ya da alt çizgi - çok fazla seçenek var ve bunlar çok daha iyi çünkü Javscript çok satırlı dizeleri desteklemiyor ve sprintf tür parametre değiştirme işlevlerini destekliyor – msanjay

7

John Resig (jQuery yaratıcısı) Aslında oldukça serin bazı özellikleri var 2008 yılında tekrar bu şablon yöntemi kullanarak önerdi: Sonra kullanarak almak

<script type="text/html" id="item_tmpl"> 

    <div id="<%=id%>" class="<%=(i % 2 == 1 ? " even" : "")%>"> 
    <div class="grid_1 alpha right"> 
     <img class="righted" src="<%=profile_image_url%>"/> 
    </div> 
    <div class="grid_6 omega contents"> 
     <p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p> 
    </div> 
    </div> 

</script> 

...

var results = document.getElementById("results"); 
results.innerHTML = tmpl("item_tmpl", dataObject); 

tüm detaylar için buraya bakınız:
http://ejohn.org/blog/javascript-micro-templating/

+2

Günümüzde, daha basit ve güzel bir adım daha ileri gidebilir ve [ICanHaz] (http://icanhazjs.com/) kullanarak bu yaklaşımı daha güzel şablonlar ve tek satırlı eleman oluşturma için Bıyık şablonlama sistemiyle birleştirebilirsiniz. –

+0

ICanHaz harika görünüyor, @MarkAmery, ama nihayet o zaman ya da Bıyık templating, ters eğik çizgi gibi bazı karakterleri çok iyi işleyemez anladım önce sadece birkaç saatimi harcadım. Bu zaman kaybını karşılayamam! – ErikE

+0

@ErikE Ouch. Icanhaz kadar çok faaliyeti olan bir kütüphanenin önemli bir şekilde kırılacağını çok şaşırdım. Bir jsfiddle'da minimum demo davası sunma şansınız var mı? Bir oyunum olabilir ve hatayı tamir edip edemeyeceğimi görebilirim. –

0

yapıyorum yolu aşağıda verilmiştir. Bu kadar çok div yapıp yapmamamız gerektiğinden emin değilim ama benimle çok iyi çalıştı.

var div1 = $('<div class="colwrap_fof"></div>');  //THE COMPLEX DIV ITSELF 
var div2 = $('<div class="homeimg"></div>');     
var div21 = $('<div id="backImageDiv'+fof_index+'" class="backDiv"></div>'); 
var div22 = $('<div id="frontImageDiv'+fof_index+'" class="frontDiv"></div>'); 
div2.append(div21); 
div2.append(div22); 
div1.append(div2); 
$("#df_background").append(div1);  // ADDING the complex div to the right place  

Alkış,

+2

Merhaba @marcelosalloum, deneyimlerimden bu kesinlikle acı vericidir.Evet, işe yarıyor ve performans hakkında yorum yapamam, ancak bunu sürdürmek çok acı verici .. – Ads

+0

Amacınız sadece bir şablon oluşturmak ve sonra da bazı verilerle doldurmaksa, kişisel olarak sadece bir display: none; 'şablon öğeleri için kapsayıcı, getElementById() veya jQuery kullanarak javascript değişkenlerine getirin, klonlayın, sonra kendimi doldurma verilerini işleyin (.textContent = val/.text (val), .setAttribute (attr, val)) /. attr (attr, val)) çünkü bunu yapmak daha kolay bir şeydir, çünkü bazı shoddy templating kütüphanelerinin işini doğru bir şekilde yapıp yapamayacağından endişelenmekten çok daha fazlasıdır çünkü şablonla ne yapmak istediğimi tam olarak biliyorum. –

2

JavaScript kodu HTML etiket yapısını andıran eğer daha okunabilir ve muhafaza edilebilir. $ ('Div', {'class': 'etc'}) kullanarak resmi jQuery yoluna gidebilirsiniz ...

Her öğeyi düzenlenebilir jQuery nesnesi yapmak için $$ işlevini kullanarak biraz farklı bir yaklaşım . Bir html ayrıştırma gerçekleşmediğinden oldukça hızlı olmalı.

$$('div', {'id':'container'}, 
    $$('div', {'id':'my_div'}, 
     $$('h1',{'class':'my_header'}, 
      $$('a',{'href':'/test/', 'class':'my_a_class'}, 'teststring')))); 

Bu yaklaşım, daha esnek hale getirir ve, örneğin kolayca zincir kullanarak iç içe jQuery nesnelere olay işleyicileri, veri vb ekleyebilir

$$('div', {'id':'container'}, 
    $$('div', {'id':'my_div'}, 
     $$('h1',{'class':'my_header'}, 
      $$('a', { 'href': '/test/', 'class': 'my_a_class' }, 'teststring') 
     ).click(function() { alert('clicking on the header'); }) 
    ).data('data for the div') 
).hide(); 

kod biri) (.text(), .html (vs.) .Append ayrı aramalar ile yapmak resmi jQuery yaklaşımını kullanmak göre daha eğer daha okunabilir veya jQuery'i beslenmesiyle $ birleştirilmiş HTML dizesi.

Referans fonksiyonu $$:

function $$(tagName, attrTextOrElems) { 
    // Get the arguments coming after the params argument 
    var children = []; 
    for (var _i = 0; _i < (arguments.length - 2) ; _i++) { 
     children[_i] = arguments[_i + 2]; 
    } 

    // Quick way of creating a javascript element without JQuery parsing a string and creating the element 
    var elem = document.createElement(tagName); 
    var $elem = $(elem); 

    // Add any text, nested jQuery elements or attributes 
    if (attrTextOrElems) { 
     if (typeof attrTextOrElems === "string") { // text 
      var text = document.createTextNode(attrTextOrElems); 
      elem.appendChild(text); 
     } 
     else if (attrTextOrElems instanceof jQuery) { // JQuery elem 
      $elem.append(attrTextOrElems); 
     } 
     else // Otherwise an object specifying attributes e.g. { 'class': 'someClass' } 
     { 
      for (var key in attrTextOrElems) { 
       var val = attrTextOrElems[key]; 
       if (val) { 
        elem.setAttribute(key, val); 
       } 
      } 
     } 
    } 

    // Add any further child elements or text  
    if (children) { 
     for (var i = 0; i < children.length; i++) { 
      var child = children[i]; 
      if (typeof child === "string") { // text 
       var text = document.createTextNode(child); 
       elem.appendChild(text); 
      } else { // JQuery elem 
       $elem.append(child); 
      } 
     } 
    } 
    return $elem; 
} 
İlgili konular