2009-06-28 58 views
1

我有種感覺我濫用DOM我的代碼...替代的innerHTML

for(var i=0; i<json.length; ++i){  
    var newobj = document.createElement("div"); 
    var inner = "<img src='"+json[i].picture+"' alt='Item preview' class='icon' />"; 

    inner += "<p>"+json[i].id+"<br />qty:"+json[i].qty; 
    inner += "<a href=\"javascript:clearProduct('"+json[i].id+"')\">"; 
    inner += "<img alt='Seperator' src='images/form-sep.gif' />"; 
    inner += "<img src='images/cross.png' alt='Remove this item.' title='Remove this item.' />"; 
    inner += "</a></p>"; 
    newobj.innerHTML = inner; 
    newobj.className = "cart_item"; 
    $('cartitems').appendChild(newobj); 
    $('cartcount').innerHTML = json.length; 
} 

有沒有更好的方式來做到這一點?我的意思是,是的,我可以通過併爲每個元素使用createElement並單獨設置每個屬性,但當這非常簡單時,看起來很多。有沒有更好的辦法?

+2

您使用的是圖書館嗎?或者是你自己的$函數? – 2009-06-28 07:38:40

+1

我正在使用原型庫。 – MackDaddy 2009-06-28 07:44:48

+0

你不應該使用var來聲明你的變量,將它們的作用域限制在循環中? – 2009-06-28 08:15:53

回答

5

我喜歡創建一個漂亮的元素創建界面;是這樣的:

function el(name, attrs) { 

    var elem = document.createElement(name), 
     styles = attrs.style; 

    for (var prop in styles) { 
     try { 
      elem.style[prop] = styles[prop]; 
     } catch(e) {} 
    } 

    for (var attr in attrs) { 
     if (attr === 'style') { continue; } 
     elem[attr] = attrs[attr]; 
    } 

    return elem; 

} 


var myImage = el('img', { 
    src: '/path/to/image.jpg', 
    alt: 'Really cool image', 
    style: { 
     border: '1px solid red', 
     padding: '10px' 
    } 
}); 
2

我不知道原型,但我通常在jQuery的建設我的對象是這樣的:

$("<p>").append(
    $("<img>") 
    .attr("alt", "Sperator") 
    .attr("src", "images/form-sep.gif") 
).append(
    $("<img>") 
    ... etc ... 
) 
2

您可以使用document.createElement()建立在你的DOM樹的每一個元素 - 但這確實是這樣更笨拙(儘管可以說更「正確」)。更不用說在IE上慢一點。我之前遇到過這個問題--DOM操作對IE來說非常緩慢。通過innerHTML分配一大堆元素的速度要快幾個數量級。當然,如果你只是創造一些元素,你就不會感覺到它。但是對於一張10x300的桌子,它需要幾秒鐘(我的舊Sempron 2200+個人電腦上超過10個)。

0

我從不使用innerHTML。如果您嘗試將字符串附加到innerHTML,然後再引用DOM對象,則可能會在IE中遇到麻煩。在很多情況下,我可以安全地使用innerHTML,但我認爲沒有理由。我首選的成語是如下創建每個DOM對象,然後添加文字:

var div = document.createElement('div'); 
div.appendChild(document.createTextNode('This is the inner text')); 

不過,我使用一些縮寫,所以我的代碼實際上是這樣的:

var div = dec('div'); 
div.appendChild(dct('This is the inner text')); 

我想以便簡化appendChild()方法,因爲這是一種常用的JavaScript方法,但如果您嘗試通過創建.ac()方法嘗試並修補DOM,IE也會抱怨。

0

TBH,除非您使用的是預卷庫(或足夠OCDish寫你自己的),你可能最好關閉使用的innerHTML,只要IE < 8是重要的因素(考慮到企業IT的惰性,這將是一段很長的時間)。在IE8之前的IE瀏覽器(使用術語鬆散地)DOM實現是非常麻煩的,非標準的和不完整的,至少任何可用的完整代碼都會滿足條件和特殊情況。

FWIW,我發現從數據表示中構建HTML最爲明顯,其代碼儘可能地假設了一個工作的DOM,並通過IE的事後修復來完成代碼的加載瀏覽器。

這裏是你的代碼是什麼樣子:

horus.appendChild 
    ('cartitems', 
    [ 'div', '.cart_item', 
    [ 'img', { src: json[i].picture, alt: 'Item preview', classname: 'icon' } ], 
    [ 'p', null, 
     json[i].id, [ 'br' ], json[i].qty, 
     [ 'a', { href: 'javascript:clearProduct('+json[i].id+')' }, 
     [ 'img', { alt: 'Seperator', src: 'images/form-sep.gif' } ], 
     [ 'img', { src: 'images/cross.png', title: 'Remove this item.' } ] ] ] ]); 

horus.childText('cartcount', json.length); 

我不打算在這裏發表我們的圖書館在他們的全部,但在here 看看(開始於線574,與肉的743)如果你很好奇,在here的IE修復代碼。

1

每當我通過JS做複雜的元素創建 - 我通常使用原型插值方法。

爲此,請在HTML中爲要創建的元素創建一個模板,並使用display:none將其放在頁面的底部,以便將其隱藏。然後使用Prototype的插值方法用您的內容替換特定字段: http://www.prototypejs.org/api/string/interpolate並在html上調用show()使其可見。