11

I'm working with ExtJs on IE9.. and i almost always get this error..

Microsoft JScript runtime error:

Object doesn't support property or method 'createContextualFragment'

What dose it means? What 'createContextualFragment' is needed for? And how to fix this?

obenjiro
  • 3,665
  • 7
  • 44
  • 82

6 Answers6

25

createContextualFragment() is a method of Range objects that creates a document fragment from an HTML string. It's present in Firefox and WebKit and Opera but is currently non-standard (it's not in the DOM Level 2 Range spec but is in the work-in-progress DOM Parsing and Serialization spec) and IE 9 didn't implement it, which is consistent with Microsoft's general approach to implementing standard functionality in IE 9 that was previously missing in IE. ExtJs must be using this method, although rather foolishly since it is non-standard and the same result can easily be achieved using innerHTML, which is supported everywhere.

UPDATE

You can patch the following into IE 9 since it allows extension of host object prototypes, which previous versions did not. The following is a naive implementation of createContextualFragment() adapted from my Rangy library but is suitable for most uses. See this Rangy issue for details and for a more thorough implementation.

Note that this will not work in IE < 9 because those browsers have no DOM Range implementation.

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;
    };
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • can i somehow.. 'emulate' this method to make ExtJs work with IE9 (i don't like IE8 emulation mode)? – obenjiro Mar 21 '11 at 09:38
  • @tim-down Downvoter is http://stackoverflow.com/users/135952/nissan-fan.. he have some 'grudge' againts me, and he downvote some of my questions\answers.. sorry for involving you into this.. – obenjiro Mar 23 '11 at 09:41
  • @Ai_boy: No problem. I just didn't think I'd said anything inaccurate or even provocative (which I do sometimes), so I was a bit surprised :) – Tim Down Mar 23 '11 at 09:46
  • 2
    For me, this patch caused problem in IE8, which apparently lacks the Range object altogether. So I changed the conditional to if (typeof Range != "undefined" && typeof Range.prototype.createContextualFragment == "undefined") – Jim Davis Jul 29 '11 at 14:14
  • @Jim: Yes, this answer makes no attempt to deal with IE version prior to version 9. If you need Range support in IE < 9, you can use Rangy (http://code.google.com/p/rangy/). – Tim Down Jul 29 '11 at 15:35
  • The code above does not work in IE9. Getting the document seams to fail. – xotix Apr 03 '12 at 09:00
  • @xotix: You're right, there was a bug. I've updated my answer. – Tim Down Apr 03 '12 at 11:28
  • Pasting the fix into ext-all gives me a `SCRIPT438: Object doesn't support property or method 'createElement'` error on the `var container` line. Fwiw. – ruffin Aug 27 '12 at 20:41
  • These solutions have stopped working since some update... now it has a problem with 'Range' not existing as well. The best thing for those of us who can't update ExtJS to do is the X-UA-Compatible metatag. –  Sep 18 '12 at 16:47
  • We implemented this solution and it was working, but in a recent Windows update it seems to have broken it... –  Sep 19 '12 at 13:40
  • @RiverC: It will fail in IE9 Compatibility View, which (like older versions of IE) has no Range support. Could that be the issue? – Tim Down Sep 19 '12 at 13:45
  • I think so. So you'd need to force it into IE9 Strict mode then? –  Sep 19 '12 at 23:35
  • @RiverC: Yes, I think so. I'm not an expert in IE modes but it seems this is possible: http://blogs.msdn.com/b/jonbox/archive/2011/03/27/removing-the-ie9-compatibility-button-and-html1115-warning.aspx – Tim Down Sep 20 '12 at 08:25
  • This resolved the situation for me - what was weird was that this issue only occurred (for me) for a new installation of IE9 - a downgrade from IE10 to IE9 to try and reproduce this issue, continued to work as in IE10 - however a new install did exhibit the same issue. – Danlance Aug 29 '13 at 14:12
3

Faster, tighter, no looping, works in IE9+ and all non-shit browsers:

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();
  }
})();
csuwldcat
  • 8,021
  • 2
  • 37
  • 32
  • @TimDown check out this new hotness: it's smaller, less complex, and has better perf than the other answers. – csuwldcat Sep 12 '13 at 17:09
  • Works in IE 10 with one change: pass in an empty string into `createHTMLDocument()`. I don't have IE 9 to hand. – Tim Down Sep 12 '13 at 23:55
2

Well, with a small change, the code posted by Tim Down worked for me :

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;
    };
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
Allie
  • 21
  • 1
  • Ah, I see what you changed and the error in my code (which had `range` where I needed `this`). I've fixed my example now, which has the advantage over yours that it will work with Ranges from documents other than the current one (useful when working with iframes, for example). – Tim Down Mar 29 '11 at 13:54
2

extjs 3.4.0 fixes this issue. No need to change the code bade. Good work on the library, though.

aldosa
  • 327
  • 1
  • 2
  • 9
1

This has already been fixed in Ext JS 3.3 IIRC, and I imagine it will be fixed in 4.0 prior to the final release (it hasn't even hit beta as of this writing).

Brian Moeskau
  • 20,103
  • 8
  • 71
  • 73
1

I've just applied Tim Down's fix to our ext 3.3.1 installation, because IE9 still doesn't display our pages correctly without it. In other words, I don't think this fix got into EXTJS 3.3, at least not the public version.

shw2
  • 11
  • 1
  • 5
    Just put this in the HTML header section ``, so there will be no problem with IE9 :) Really, one line of 'html' code and your app will be working just fine with IE9 – obenjiro Apr 20 '11 at 06:51