我有一张这样的表:
<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无法在<tbody>
上设置innerHTML。任何人都可以帮我解决这个问题的简单解决方法吗?
答案 0 :(得分:32)
确实如此,tbody元素上的innerHTML在IE中是readOnly
该属性对所有人都是可读/写的 对象除了以下对象 它是只读的: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
。然后,它会从注入的tbody
替换tbody
和table
。如果证明速度很慢,您可以通过缓存temp
而不是每次都创建它来加快速度。
答案 1 :(得分: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);
}
答案 2 :(得分: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中可能包含的最大单元格数。虽然表tbody是50个单元格宽,但只有两列显示。也许如果表最初填充,并且单元格被替换为相同的内部结构,则此方法可行。谷歌的Chrome在重建表格方面做得非常出色,而Opera的桌面浏览器可以很好地调整到更多的列,但是如果删除列,剩余的列宽仍然保持原样;但是对于Opera,通过隐藏表(display = none)然后重新显示它(display = table),生成的表tbody单元然后正确地调整大小。我放弃了Firefox。它是2012年的MSIE-6 - 开发的噩梦,必须添加额外的标记才能使HTML-CSS布局工作,因为它不符合甚至MSIE现在所做的标准。所以我还没有测试过Firefox中的tbody.innerHTML工作。
答案 3 :(得分: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)
答案 4 :(得分: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>