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

Javascript 为什么IE在设置innerHTML时会出现意外错误,javascript,internet-explorer,innerhtml,Javascript,Internet Explorer,Innerhtml,我试着在firefox中的一个元素上设置innerHTML,它工作得很好,在IE中试过,但没有明显的原因就出现了意外的错误 例如,如果您尝试将表格的innerHTML设置为“hi from stu”,它将失败,因为表格后面必须有一个序列。我刚刚发现,如果您尝试在IE中逻辑不正确的元素上设置innerHTML,它将抛出此错误。 例如,如果尝试将表的innerHTML设置为“hi from stu”,它将失败,因为该表后面必须跟一个序列。 显然firefox并没有这么挑剔。 希望能有所帮助。“显然f

我试着在firefox中的一个元素上设置innerHTML,它工作得很好,在IE中试过,但没有明显的原因就出现了意外的错误


例如,如果您尝试将表格的innerHTML设置为“hi from stu”,它将失败,因为表格后面必须有一个序列。

我刚刚发现,如果您尝试在IE中逻辑不正确的元素上设置innerHTML,它将抛出此错误。 例如,如果尝试将表的innerHTML设置为“hi from stu”,它将失败,因为该表后面必须跟一个序列。 显然firefox并没有这么挑剔。 希望能有所帮助。

“显然firefox并没有这么挑剔”==>显然firefox有很多缺陷,没有明显违反基本的html嵌套规则


正如有人在另一个论坛中指出的那样,FireFox会接受这样一种说法,即您将整个html文档作为表单字段甚至图像的子项进行附加(

您是否尝试过设置innerText和/或textContent?一些节点(如脚本标记)当您尝试在IE中更改其innerHTML时,其行为将不符合预期。有关innerText与textContent的更多信息:


我不知道为什么你会因为Stu的问题而被修改,因为这是我最近解决的问题。诀窍是将HTML“喷射”到当前未附加到文档树的DOM元素中。下面是执行此操作的代码片段:

// 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...
//删除脚本以避免IE中出现任何“权限被拒绝”错误
var=html.replace(//g,“”);
//IE对格式错误的HTML直接注入DOM更为严格
//一个尚未成为DOM一部分的元素,它更宽松,并将清理它。
if(jQuery.browser.msie)
{
var tempElement=document.createElement(“DIV”);
tempElement.innerHTML=已清理;
cleaned=tempElement.innerHTML;
tempElement=null;
}
//现在“清洁”可以使用了。。。

注意:我们在这段代码中只使用jQuery来测试浏览器是否是IE,对jQuery没有硬依赖。

您是在设置一个完全不同的innerHTML还是在innerHTML中替换一个模式?我这样问是因为如果您试图通过innerHTML的“强大”进行简单的搜索/替换,您会发现一些类型不在IE中使用的元素

这可以通过在try/catch中包围您的尝试,并通过parentNode向上冒泡DOM,直到您成功地做到这一点来谨慎地纠正


但是,如果要插入全新的内容,这将不合适。

请检查您试图设置innerHTML的元素的范围。由于FF和IE以不同的方式处理此问题,您会看到这种行为,因为innerHTML对于IE中的表元素是只读的。从MSDN文档中可以看出:

该属性对除以下对象之外的所有对象都是读/写的,对于这些对象它是只读的:COL、COLGROUP、FRAMESET、HEAD、HTML、STYLE、TABLE、TBODY、TFOOT、THEAD、TITLE、TR


我一直在努力解决用不同的链接列表替换表中的链接列表的问题。如上所述,IE及其表元素的只读属性带来了问题

附加对我来说不是一个选项,所以我(最终)解决了这个问题(它适用于Ch、FF和IE 8.0(还可以尝试其他版本,但我充满希望))

replaceInReadOnly(document.getElementById(“links”),“”);
函数replaceInReadOnly(元素、内容){
var newNode=document.createElement();
newNode.innerHTML=内容;
var oldNode=element.firstChild;
var输出=element.replaceChild(newNode,oldNode);
}

对我有效-我希望它对您有效

您可以修改该行为。以下是一些代码,用于防止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)

一段代码摘录可能很有用……浏览器的目的是尽可能地向用户提供信息——这意味着试图从作者错误中恢复过来。我的观点是:Stackoverflow旨在成为一个人们可以为技术问题寻求良好技术答案的地方。我发现了这一点我觉得这不明显,我想我会把它加入知识库。不写一个问题是不可能做到的,所以我做了并回答了。你可能会被否决,因为这个答案中的大部分实际上都属于这个问题——你最初并没有说清楚你想做什么。我现在把其中的一些转移到了这个问题上。有意思吗ting的故事。IE有这个bug并不是什么大问题。但是,我很生气他们知道这个bug至少有12年了,但它仍然没有被修复。它出现在IE8中。这也给我的脚本对象带来了问题。
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)