Почему IE выдает неожиданные ошибки при настройке innerHTML


Я попытался установить innerHTML на элемент в firefox, и он работал нормально, попробовал его в IE и получил неожиданные ошибки без очевидной причины.

Например, если вы попытаетесь установить значение innerHTML таблицы в "привет от stu", это не удастся, потому что за таблицей должна следовать последовательность.

10 6

10 ответов:

"видимо firefox не такой придирчивый" = = > видимо FireFox настолько глючный, что он не регистрирует это явное нарушение основных правил html-вложенности ...

Как кто-то указал на другом форуме, FireFox примет, что вы добавляете весь html-документ как дочернее поле формы или даже изображение,- (

Вы видите такое поведение, потому что innerHTML доступен только для чтения элементов таблицы в IE. Из документации MSDN innerHTML Property:

Свойство доступно для чтения/записи для всех объектов, за исключением следующих, для которых оно доступно только для чтения: коль, элемент colgroup, фреймов, головке, HTML, стиль, стол, элемента tbody, TFOOT, элементы thead, заголовок, ТР.

Не знаю, почему вы понижаете моду на вопрос Стю, поскольку это то, что я решил совсем недавно. Хитрость заключается в том, чтобы "впрыснуть" 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...

Примечание мы используем только использование jQuery в этом фрагменте кода, чтобы проверить, является ли браузер IE, нет жесткой зависимости от jQuery.

Проверьте область действия элемента, который вы пытаетесь задать innerHTML. поскольку FF и IE обрабатывают это по-разному

Я боролся с проблемой замены списка ссылок в таблице другим списком ссылок. Как и выше, проблема связана с IE и его свойством только для чтения элементов таблицы.

Добавить для меня не было вариантом, поэтому я (наконец) разработал это (что работает для 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);
}

Работает для меня-я надеюсь, что это работает для вас

Вы пробовали устанавливать innerText и / или textContent? Некоторые узлы (например, теги скриптов) не будут вести себя так, как ожидалось при попытке изменить их innerHTML в IE. Больше здесь примерно через свойство innerText против текстового содержимого:

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

Вы устанавливаете совершенно другой innerHTML или заменяете шаблон в innerHTML? Я спрашиваю, потому что, если вы пытаетесь сделать тривиальный поиск/замену через "силу" innerHTML, вы найдете некоторые типы элементов, не играющих в IE.

Это можно осторожно исправить, окружив вашу попытку в try / catch и пузырясь DOM через parentNode, пока вам не удастся это сделать.

Но это не будет подходящим, если вы вставляете совершенно новый содержание.

Вы можете изменить поведение. Вот некоторый код, который предотвращает сборку мусора из элементов с другими ссылками в 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/

Я только что выяснил, что если вы попытаетесь установить innerHTML на элемент в IE, который логически не корректен, он выдаст эту ошибку. Например, если вы попытаетесь установить значение innerHTML таблицы в " hi from stu ", это не удастся, потому что за таблицей должна следовать последовательность. Очевидно, firefox не настолько разборчив. Надеюсь, это поможет.