2011-01-18 77 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>