无法在 IE 中的 tbody 上设置 innerHTML

IT技术 javascript internet-explorer
2021-01-28 09:45:52

我有一张这样的表:

<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>. 任何人都可以帮助我解决此问题的简单解决方法吗?

5个回答

确实如此,tbody 元素上的innerHTML 在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. 然后,它取代了tbodytbody从注入table如果证明它很慢,您可以通过缓存temp而不是每次都创建它来使其更快

不太好:替换丢失了所有原始属性,例如问题中的 id="replaceMe"。
2021-03-15 09:45:52
@NINtenderinput是一个自结束标签,它没有innerHTML.
2021-03-25 09:45:52
var myTableBody = document.getElementById('tbody Id 的值');setTBodyInnerHTML(myTableBody, "value to add");
2021-03-29 09:45:52
没有比这更愚蠢的了
2021-04-07 09:45:52

创建一个临时节点来存储表,然后将它们复制到 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);
  } 

上面的两个答案似乎都有些不清楚。另外,创建的 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 个单元格宽,但只显示了两列。或许如果表格原本是填充的,而单元格被替换为相同的内部结构,这种方法会奏效。Google 的 Chrome 在重建表格方面做得非常出色,而 Opera 的桌面浏览器可以很好地调整到更多列的大小,但是如果删除列,剩余的列宽仍然保持原来的窄;但是对于 Opera,通过隐藏表格 (display=none) 然后重新显示它 (display=table),生成的表格 tbody 单元格然后大小合适。我已经放弃了 Firefox。这是 2012 年的 MSIE-6 - 一个开发的噩梦,必须添加额外的标记才能使 HTML-CSS 布局工作,因为它不符合甚至 MSIE 现在所做的标准。所以我还没有在 Firefox 中测试 tbody.innerHTML 的工作原理。

该节点在函数退出后被垃圾收集,因为它没有附加到 DOM。
2021-04-03 09:45:52

这可以通过为 .innerHTML 创建一个 shim/polyfill 来解决。这可以让你(你,亲爱的读者)开始:

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/

<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>
您能否添加对建议解决方案的简要总结?
2021-03-19 09:45:52