Search code examples
javascriptjqueryinternet-explorerdomrangy

jQuery doesn't support .has in IE8? what is a work around?


code: http://jsfiddle.net/4hV6c/4/ just make any selection, and you'll get a script error in ie8

I'm trying to do this:

$(end_node.parentNode).has(start_node)

which in modern browsers (chrome, ff, opera, etc) returns [] if start_node is not in end_node.parentNode, and returns the element (I forget which) if it is found.

now, end_node is a text element, and the parentNode is an actual DOM entity. IE will perform .has on just $(end_node).has(start_node) but that is obviously different behavior.

Is there a work around to get this to work?

  • in IE the fiddle will error, other browsers will alert you with a boolean value.

UPDATE: here is a word around that overrides .has() for my specific scenario.. not sure if it works for all the cases of .has, as I don't know them all. http://jsfiddle.net/8F57r/13/


Solution

  • The problem is not jQuery

    Running

    console.log( $("div:has(span)").html() );
    console.log( $("div").has($("span")[0]).html() );
    

    However, the following throws an exception http://jsfiddle.net/mendesjuan/4hV6c/8/

    var textNode =  $("span")[0].childNodes[0];
    $("div").has(textNode);
    

    What that means is that you can't pass a text node into $.has. You should file a bug with jQuery

    The line that is erroring out is giving the following message

    No such interface supported jquery-1.7.1.js, line 5244 character 3

    That is trying to call the contains method on a node. What that means is that this really is an IE bug that jQuery hasn't worked around. I've reproduced the problem without needing to call $.has http://jsfiddle.net/4hV6c/10/

    // This is broken in IE
    var textNode =  $("span")[0].childNodes[0];
    var divNode = $("div")[0];
    divNode.contains(textNode);
    

    Workaround http://jsfiddle.net/4hV6c/12/

    function contains(outer, inner) {
       var current = inner;
        do {
            if (current == outer) {
               return true;
            }
        } while((current = current.parentNode) != document.body);
    
        return false;
    
    }
    rangy.init();
    
    $(document).bind("mouseup", function() {
        var a = rangy.getSelection();
        start_node = a.anchorNode;
        end_node = a.focusNode;
        var b = a.getRangeAt(0);
        var c = b.commonAncestorContainer;
        b.selectNodeContents(c);
        a.setSingleRange(b);
        alert( contains( end_node.parentNode, start_node) );
    });