Almost native matchesSelector() for IE8

Modern browsers support a handy JavaScript method matchesSelector() (renamed to matches() in latest versions of the standard). The method allows to determine if an element matches a selector. In all supporting browsers, this method is still prefixed, but it’s quite stable (which is no wonder since in essence such ability has always been available — just in CSS only) and among others is utilized in Sizzle — the selector engine used in jQuery.

Determining whether an element matches a selector is one of key features that allow not to use libraries like jQuery for binding event handlers without need to traverse all elements that these handlers are intended for, while keeping enough ease of use for programmer.

Internet Explorer supports matchesSelector() (represented by the prefixed msMatchesSelector() variant) as of version 9 only. But what to do with IE8, which we are still forced to support in many cases?

In IE8, it’s possible to use another native DOM method — querySelectorAll().

function matchesSelectorIe8(elem, selector) {
    // http://tanalin.com/en/blog/2012/12/matches-selector-ie8/
    var elems = elem.parentNode.querySelectorAll(selector),
        count = elems.length;

    for (var i = 0; i < count; i++) {
        if (elems[i] === elem) {
            return true;
        }
    }

    return false;
}

The idea is to traverse all descendants of the parent element of the subject element that match the selector, and then compare all these descendants with the subject element.

Performance of this method is inversely proportional to number of descendants to check, but it should generally be faster than a pure-script selector engine, so the method is quite applicable as a compact solution for an obsolete browser in most cases when using bulky third-party libraries is undesired or unreasonable.

Of course do not forget about IE8’s selector-support limitations that take place in both CSS and JavaScript equally: for example, there is no support for the :last-child pseudoclass, and we cannot change that. Fortunately, unlike CSS, JavaScript is a programming language, so it’s possible to workaround lack of support for things like :last-child with some trivial extra code.


You may also be interested in getElementsByClassName() for IE8.