【问题标题】:ExtJs4 + IE9 = Object doesn't support property or method 'createContextualFragment'ExtJs4 + IE9 = 对象不支持属性或方法'createContextualFragment'
【发布时间】:2011-03-21 09:10:59
【问题描述】:

我在 IE9 上使用 ExtJs.. 我几乎总是得到这个错误..

Microsoft JScript 运行时错误:

对象不支持属性或 方法'createContextualFragment'

这意味着什么剂量?需要什么'createContextualFragment'?以及如何解决这个问题?

【问题讨论】:

    标签: javascript extjs internet-explorer-9


    【解决方案1】:

    createContextualFragment()Range 对象的一种方法,它从 HTML 字符串创建文档片段。它存在于 Firefox 和 WebKit 和 Opera 中,但目前是非标准的(它不在 DOM Level 2 Range spec 中,但在进行中 DOM Parsing and Serialization spec 中)并且 IE 9 没有实现它,这与微软的一般在 IE 9 中实现标准功能的方法,这是以前在 IE 中缺少的。 ExtJs 必须使用这种方法,虽然相当愚蠢,因为它是非标准的,并且使用 innerHTML 可以轻松实现相同的结果,这在任何地方都受支持。

    更新

    您可以将以下内容修补到 IE 9 中,因为它允许扩展宿主对象原型,而以前的版本没有。以下是createContextualFragment() 的一个幼稚实现,改编自我的Rangy library,但适用于大多数用途。请参阅this Rangy issue 了解详细信息和更彻底的实施。

    请注意,这在 IE

    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;
        };
    }
    

    【讨论】:

    • 我能以某种方式..“模拟”这种方法以使 ExtJs 与 IE9 一起工作(我不喜欢 IE8 模拟模式)?
    • @tim-down Downvoter 是stackoverflow.com/users/135952/nissan-fan.. 他对我有一些“怨恨”,他对我的一些问题\答案投了反对票.. 很抱歉让你参与其中..
    • @Ai_boy:没问题。我只是不认为我说了什么不准确甚至挑衅的话(我有时会这样做),所以我有点惊讶:)
    • 对我来说,这个补丁在 IE8 中引起了问题,它显然完全没有 Range 对象。所以我把条件改成了 if (typeof Range != "undefined" && typeof Range.prototype.createContextualFragment == "undefined")
    • @Jim:是的,这个答案没有尝试处理 IE 版本 9 之前的版本。如果您需要 IE code.google.com/p/rangy)。跨度>
    【解决方案2】:

    更快、更紧凑、无循环,适用于 IE9+ 和所有非垃圾浏览器:

    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();
      }
    })();
    

    【讨论】:

    • @TimDown 看看这个新热点:它比其他答案更小、更简单、性能更好。
    • 在 IE 10 中工作,但有一个变化:将一个空字符串传入createHTMLDocument()。我手头没有 IE 9。
    【解决方案3】:

    嗯,稍作改动,Tim Down 发布的代码对我有用:

    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;
        };
    }
    

    【讨论】:

    • 啊,我看到了您所做的更改以及我的代码中的错误(在我需要 this 的地方有 range)。我现在已经修复了我的示例,与您的示例相比,它的优势在于它可以与当前文档以外的文档中的范围一起使用(例如,在使用 iframe 时很有用)。
    【解决方案4】:

    extjs 3.4.0 修复了这个问题。无需更改代码。不过,图书馆做得很好。

    【讨论】:

      【解决方案5】:

      这已经在 Ext JS 3.3 IIRC 中修复,我想它会在最终版本之前的 4.0 中修复(在撰写本文时它甚至还没有达到测试版)。

      【讨论】:

        【解决方案6】:

        我刚刚对我们的 ext 3.3.1 安装应用了 Tim Down 的修复,因为没有它,IE9 仍然无法正确显示我们的页面。换句话说,我认为这个修复不会进入 EXTJS 3.3,至少不是公共版本。

        【讨论】:

        • 只需将它放在 HTML 标题部分 <meta http-equiv="X-UA-Compatible" content="IE=8" />,这样 IE9 就不会出现问题 :) 真的,一行 'html' 代码和您的应用程序将在 IE9 上正常工作
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2014-10-19
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        • 2015-04-14
        相关资源
        最近更新 更多