2009-06-28 56 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()使其可见。