ExtJs4 + IE9 = Объект не поддерживает свойство или метод 'createContextualFragment'

Я работаю с ExtJs на IE9.. и я почти всегда получаю эту ошибку.

Ошибка выполнения Microsoft JScript:

Объект не поддерживает свойство или метод 'createContextualFragment'

Какая доза это означает? Для чего нужен "createContextualFragment"? И как это исправить?

Ответ 1

createContextualFragment() - это метод объектов Range, который создает фрагмент документа из строки HTML. Он присутствует в Firefox и WebKit и Opera, но в настоящее время нестандартен (не в спецификации уровня DOM уровня 2, но находится в процессе работы DOM Parsing and Serialization spec), и IE 9 не реализовал его, что согласуется с общим подходом Microsoft к внедрению стандартных функций в IE 9, который ранее отсутствовал в IE. ExtJs должен использовать этот метод, хотя довольно глупо, так как он нестандартен, и тот же результат может быть легко достигнут с помощью innerHTML, который поддерживается везде.

UPDATE

Вы можете исправить следующее в IE 9, поскольку оно позволяет расширять прототипы объектов хоста, которых не было в предыдущих версиях. Ниже приведена наивная реализация createContextualFragment(), адаптированная из моей библиотеки Rangy, но подходит для большинства целей. См. эту проблему Rangy для получения более подробной информации и для более полной реализации.

Обратите внимание, что это не будет работать в IE < 9, поскольку эти браузеры не имеют реализации DOM Range.

if (typeof Range.prototype.createContextualFragment == "undefined") {
    Range.prototype.createContextualFragment = function(html) {
        var startNode = this.startContainer;
        var doc = startNode.nodeType == 9 ? startNode : startNode.ownerDocument;
        var container = doc.createElement("div");
        container.innerHTML = html;
        var frag = doc.createDocumentFragment(), n;
        while ( (n = container.firstChild) ) {
            frag.appendChild(n);
        }
        return frag;
    };
}

Ответ 2

Быстрее, жестче, без циклов, работает в IE9 + и всех не-shit-браузерах:

var createContextualFragment = (function(){
  var doc = document.implementation.createHTMLDocument(''),
      range = doc.createRange(),
      body = doc.body;
  return function(html){
    body.innerHTML = html;
    range.selectNodeContents(body);
    return range.extractContents();
  }
})();

Ответ 3

Ну, с небольшим изменением код, отправленный Тимом Дауном, работал у меня:

if (typeof Range.prototype.createContextualFragment == "undefined") {
    Range.prototype.createContextualFragment = function (html) {
        var doc = window.document;
        var container = doc.createElement("div");
        container.innerHTML = html;
        var frag = doc.createDocumentFragment(), n;
        while ((n = container.firstChild)) {
            frag.appendChild(n);
        }
        return frag;
    };
}

Ответ 4

extjs 3.4.0 устраняет эту проблему. Не нужно менять код. Хорошая работа в библиотеке.

Ответ 5

Это уже было исправлено в Ext JS 3.3 IIRC, и я полагаю, что он будет исправлен в 4.0 до финальной версии (он даже не попал в бета-версию на момент написания этой статьи).

Ответ 6

Я только что применил исправление Tim Down к нашей установке ext 3.3.1, потому что IE9 по-прежнему не отображает наши страницы правильно без него. Другими словами, я не думаю, что это исправление попало в EXTJS 3.3, по крайней мере, не в общедоступной версии.