2011-01-18 47 views
22

我有一个表是这样的:无法设置的innerHTML上TBODY在IE

<table> 
<thead> 
    <tr> 
     <th colspan="1">a</th> 
     <th colspan="3">b</th> 
    </tr> 
</thead> 
<tbody id="replaceMe"> 
    <tr> 
     <td>data 1</td> 
     <td>data 2</td> 
     <td>data 3</td> 
     <td>data 4</td> 
    </tr> 
</tbody> 
</table> 

和方法返回我一个Ajax请求后,执行以下操作:

<tr> 
    <td>data 1 new</td> 
    <td>data 2 new</td> 
    <td>data 3 new</td> 
    <td>data 4 new</td> 
</tr> 

我想改变innerHTML的像

document.getElementById('replaceMe').innerHTML = data.responseText; 

然而,似乎IE不能设置的innerHTML上<tbody>。任何人都可以帮助我解决这个问题的一个简单的解决方法?

+2

此外,使用类似jQuery的库不是一个选项。 – tester 2011-01-18 22:24:41

回答

32

这是事实,innerHTML的上TBODY元素是readOnly的在IE

的属性为读/写为除了以下所有 对象, 它是只读的:COL,COLGROUP, FRAMESET,HEAD,HTML,STYLE,TABLE, TBODY,TFOOT,THEAD,TITLE,TR。

来源:http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx

你可以做这样的事情来解决它:

function setTBodyInnerHTML(tbody, html) { 
    var temp = tbody.ownerDocument.createElement('div'); 
    temp.innerHTML = '<table>' + html + '</table>'; 

    tbody.parentNode.replaceChild(temp.firstChild.firstChild, tbody); 
} 

基本上它创建你注入一个完整table成一个临时的节点。然后它从注入的table替换tbodytbody。如果证明速度慢,则可以通过缓存temp而不是每次创建它来加快速度。

+0

我该如何使用它? – 2012-10-23 09:22:13

+1

var myTableBody = document.getElementById('tbody Id'的值); setTBodyInnerHTML(myTableBody,“value to add”); – Matoeil 2013-04-08 10:09:15

+2

不太好:替换失去了所有原始属性,如问题中的id =“replaceMe”。 – 2014-01-24 17:34:24

6

创建于存储表中的临时节点,然后将它们复制到TBODY

var tempNode = document.createElement('div'); 
    tempNode.innerHTML = "<table>" + responseText+ "</table>"; 

    var tempTable = tempNode.firstChild; 
    var tbody = // get a reference to the tbody 
    for (var i=0, tr; tr = tempTable.rows[i]; i++) { 
    tbody.appendChild(tr); 
    } 
1

上述两个问题的答案似乎有点不清楚。另外,创建的div永远不会被删除,因此反复调用这些函数会消耗内存。试试这个:


// this function must come before calling it to properly set “temp” 
function MSIEsetTBodyInnerHTML(tbody, html) { //fix MS Internet Exploder’s lameness 
    var temp = MSIEsetTBodyInnerHTML.temp; 
    temp.innerHTML = '<table><tbody>' + html + '</tbody></table>'; 
    tbody.parentNode.replaceChild(temp.firstChild.firstChild, tbody); } 
MSIEsetTBodyInnerHTML.temp = document.createElement('div'); 

if (navigator && navigator.userAgent.match(/MSIE/i)) 
    MSIEsetTBodyInnerHTML(tbody, html); 
else //by specs, you can not use “innerHTML” until after the page is fully loaded 
    tbody.innerHTML=html;  

即使有这样的代码,但是,MSIE似乎不正确重新大小的表格单元格在我的应用程序,但我填充生成可变内容的空TBODY标签,而THEAD单元格的colspan值被设置为固定值:可能在生成的tbody中的单元格的最大数量。虽然表格的宽度为50个单元,但只有两列显示。也许如果表格最初被填满,并且单元格被替换为相同的内部结构,则此方法将起作用。谷歌Chrome浏览器在重建表格方面做得非常出色,而Opera的桌面浏览器可以调整到更多列,但如果删除列,其余列宽将保持原样;然而,通过隐藏表格(display = none),然后重新显示它(display = table),生成的表格tbody单元的大小正确。我已经放弃了Firefox。这是2012年的MSIE-6 - 开发的噩梦,必须添加额外的标记才能使HTML-CSS布局发挥作用,因为它不符合甚至MSIE现在的标准。所以我没有在Firefox中测试tbody.innerHTML运作。

1

这可以通过为.innerHTML创建填充/填充来修复。这可以让你(你,亲爱的读者)开始:

if (/(msie|trident)/i.test(navigator.userAgent)) { 
var innerhtml_get = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").get 
var innerhtml_set = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").set 
Object.defineProperty(HTMLElement.prototype, "innerHTML", { 
    get: function() {return innerhtml_get.call (this)}, 
    set: function(new_html) { 
    var childNodes = this.childNodes 
    for (var curlen = childNodes.length, i = curlen; i > 0; i--) { 
    this.removeChild (childNodes[0]) 
    } 
    innerhtml_set.call (this, new_html) 
    } 
}) 
} 

var mydiv = document.createElement ('div') 
mydiv.innerHTML = "test" 
document.body.appendChild (mydiv) 

document.body.innerHTML = "" 
console.log (mydiv.innerHTML) 

http://jsfiddle.net/DLLbc/9/

0

今天我发现自己在同样的情况。

我解决了我的问题,将整个表格标记替换为模拟表行为的浮动div和css。这样我就可以在IE中使用innerHTML而没有任何问题。

虽然这不可能是任何人的解决方案,但如果您的浮动div允许您使用,我建议您这样做。

0
<table id="table"> 
<thead> 
    <tr> 
     <th colspan="1">a</th> 
     <th colspan="3">b</th> 
    </tr> 
</thead> 
<tbody id="replaceMe"> 
    <tr> 
     <td>data 1</td> 
     <td>data 2</td> 
     <td>data 3</td> 
     <td>data 4</td> 
    </tr> 
</tbody> 
</table> 
<button type="button" onclick="replaceTbody()">replaceTbody</button> 
<script> 
function $(id){ 
    return document.getElementById(id); 
} 

function replaceTbody(){ 
    var table = $('table'); 
    table.removeChild($('replaceMe')); 
    var tbody = document.createElement("tbody"); 
    tbody.setAttribute("id","replaceMe"); 
    table.appendChild(tbody); 

    var tr = document.createElement('tr'); 
    for(var i=1;i<5;i++){ 
     var td = document.createElement('td'); 
     td.innerHTML = 'newData' + i; 
     tr.appendChild(td); 
    } 
    tbody.appendChild(tr); 
} 
</script>