简体   繁体   English

为什么IE在设置innerHTML时会出现意外错误

[英]Why does IE give unexpected errors when setting innerHTML

I tried to set innerHTML on an element in firefox and it worked fine, tried it in IE and got unexpected errors with no obvious reason why. 我试图在firefox中的一个元素上设置innerHTML并且它工作正常,在IE中尝试它并且出现意外错误,没有明显的原因。

For example if you try and set the innerHTML of a table to " hi from stu " it will fail, because the table must be followed by a sequence. 例如,如果您尝试将表的innerHTML设置为“hi from stu”,则它将失败,因为该表必须后跟一个序列。

You're seeing that behaviour because innerHTML is read-only for table elements in IE. 您正在看到这种行为,因为innerHTML对于IE中的表元素是只读的。 From MSDN's innerHTML Property documentation: 从MSDN的innerHTML属性文档:

The property is read/write for all objects except the following, for which it is read-only: COL, COLGROUP, FRAMESET, HEAD, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR. 该属性是读/写的除以下所有对象,它是只读的:COL,COLGROUP,FRAMESET,HEAD,HTML,STYLE,TABLE,TBODY,TFOOT,THEAD,TITLE,TR。

Don't know why you're being down-modded for the question Stu, as this is something I solved quite recently. 不知道你为什么要对Stu这个问题进行修改,因为这是我最近解决的问题。 The trick is to 'squirt' the HTML into a DOM element that is not currently attached to the document tree . 诀窍是将HTML“喷射”到当前未附加到文档树的DOM元素中。 Here's the code snippet that does it: 这是执行此操作的代码段:

// removing the scripts to avoid any 'Permission Denied' errors in IE
var cleaned = html.replace(/<script(.|\s)*?\/script>/g, "");

// IE is stricter on malformed HTML injecting direct into DOM. By injecting into 
// an element that's not yet part of DOM it's more lenient and will clean it up.
if (jQuery.browser.msie)
{
    var tempElement = document.createElement("DIV");
    tempElement.innerHTML = cleaned;
    cleaned = tempElement.innerHTML;
    tempElement = null;
}
// now 'cleaned' is ready to use...

Note we're using only using jQuery in this snippet here to test for whether the browser is IE, there's no hard dependency on jQuery. 请注意,我们在此片段中仅使用jQuery来测试浏览器是否为IE,对jQuery没有硬性依赖。

check the scope of the element you are trying to set the innerHTML. 检查您尝试设置innerHTML的元素的范围。 since FF and IE handle this in a different way 因为FF和IE以不同的方式处理它

I have been battling with the problem of replacing a list of links in a table with a different list of links. 我一直在努力解决用不同的链接列表替换表中链接列表的问题。 As above, the problem comes with IE and its readonly property of table elements. 如上所述,问题来自于IE及其表元素的readonly属性。

Append for me wasn't an option so I have (finally) worked out this (which works for Ch, FF and IE 8.0 (yet to try others - but I am hopeful)). 追加给我不是一个选项,所以我(最终)解决了这个问题(适用于Ch,FF和IE 8.0(但还是尝试其他人 - 但我很有希望))。

replaceInReadOnly(document.getElementById("links"), "<a href>........etc</a>");

function replaceInReadOnly(element, content){
    var newNode = document.createElement();
    newNode.innerHTML = content;
    var oldNode = element.firstChild;
    var output = element.replaceChild(newNode, oldNode);
}

Works for me - I hope it works for you 适合我 - 我希望它适合你

"Apparently firefox isn't this picky" ==> Apparently FireFox is so buggy, that it doesn't register this obvious violation of basic html-nesting rules ... “显然firefox不是这个挑剔的”==>显然FireFox是如此的错误,它没有注册这个明显违反基本的html嵌套规则......

As someone pointed out in another forum, FireFox will accept, that you append an entire html-document as a child of a form-field or even an image ,-( 正如有人在另一个论坛中指出的那样,FireFox会接受,你将一个完整的html文档附加为表单字段甚至图像的子项, - (

Have you tried setting innerText and/or textContent? 您是否尝试过设置innerText和/或textContent? Some nodes (like SCRIPT tags) won't behave as expected when you try to change their innerHTML in IE. 当您尝试在IE中更改其innerHTML时,某些节点(如SCRIPT标记)将无法按预期运行。 More here about innerText versus textContent: 更多关于innerText与textContent:

http://blog.coderlab.us/2006/04/18/the-textcontent-and-innertext-properties/ http://blog.coderlab.us/2006/04/18/the-textcontent-and-innertext-properties/

You can modify the behavior. 您可以修改行为。 Here is some code that prevents garbage collection of otherwise-referenced elements in IE: 这里有一些代码可以防止在IE中以其他方式引用的元素进行垃圾收集:

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/ http://jsfiddle.net/DLLbc/9/

Are you setting a completely different innerHTML or replacing a pattern in the innerHTML? 您是在设置完全不同的innerHTML还是替换innerHTML中的模式? I ask because if you're trying to do a trivial search/replace via the 'power' of innerHTML, you will find some types of element not playing in IE. 我问,因为如果你试图通过innerHTML的'power'做一个简单的搜索/替换,你会发现某些类型的元素没有在IE中播放。

This can be cautiously remedied by surrounding your attempt in a try/catch and bubbling up the DOM via parentNode until you successfully manage to do it. 这可以通过围绕您尝试尝试/捕获并通过parentNode冒泡DOM来谨慎解决,直到您成功设法完成。

But this is not going to be suitable if you're inserting brand-new content. 但是如果你要插入全新的内容,这将不合适。

I just figured out that if you try to set innerHTML on an element in IE that isn't logically correct it will throw this error. 我只是想通了如果你试图在IE中的一个元素上设置innerHTML,这在逻辑上是不正确的,它会抛出这个错误。 For example if you try and set the innerHTML of a table to " hi from stu " it will fail, because the table must be followed by a sequence. 例如,如果您尝试将表的innerHTML设置为“ hi from stu ”,则它将失败,因为该表必须后跟一个序列。 Apparently firefox isn't this picky. 显然firefox不是那么挑剔。 Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM