Почти родной matchesSelector() для IE8

В современных браузерах доступен удобный JavaScript-метод matchesSelector() (обновлено: в более свежих версиях стандарта метод переименован в matches()), позволяющий определить, соответствует ли элемент заданному селектору. Во всех поддерживающих браузерах этот метод пока доступен с префиксом, но работает вполне стабильно (что и не удивительно — ведь по сути такая возможность была доступна всегда, но лишь в рамках CSS) и задействован в том числе в Sizzle — движке селекторов, используемом в jQuery.

Определение соответствия элемента селектору — одна из ключевых возможностей, позволяющих обойтись без библиотек типа jQuery для назначения обработчиков событий без необходимости обхода всех элементов, для которых эти обработчики предназначены, при сохранении достаточного удобства программиста.

Internet Explorer поддерживает matchesSelector() (в виде его варианта с префиксом — msMatchesSelector()) лишь начиная с версии 9. Но что делать с IE8, поддерживать который во многих случаях по-прежнему приходится?

В IE8 можно воспользоваться встроенным DOM-методом querySelectorAll().

function matchesSelectorIe8(elem, selector) {
    // http://tanalin.com/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;
}

Идея состоит в последовательном переборе всех потомков родителя проверяемого элемента, соответствующих селектору, и сравнении их с проверяемым элементом.

Быстродействие этого метода обратно пропорционально количеству проверяемых потомков, но в общем случае он должен быть быстрее чисто скриптового движка селекторов, и в качестве компактного решения для отмирающего браузера данный метод вполне применим в большинстве случаев, когда использование громоздких библиотек нежелательно или нецелесообразно.

Разумеется, не следует забывать об ограничениях поддержки селекторов в IE8, которые в CSS и JavaScript проявляются в равной степени: например, отсутствует поддержка псевдокласса :last-child, и этого не изменить. К счастью, в отличие от CSS, JavaScript является языком программирования, и отсутствие поддержки вещей типа :last-child обходится с помощью довольно тривиальной дополнительной логики.


Вас также может заинтересовать getElementsByClassName() для IE8.