Marat Tanalin's solution is fine, but the standard syntax for elem.matchesSelector
is elem.matches
:
function getAncestorBySelector(elem, selector) {
if (!elem.matches(selector + ' ' + elem.tagName)) {
// If element is not inside needed element, returning immediately.
return null;
}
// Loop for finding an ancestor element that matches your selector.
}
Unfortunately, not all browsers support this syntax yet. Several browsers still implement a prefixed version of elem.matchesSelector
and Opera Mini doesn't support this feature at all.
To alleviate that issue, you could combine the approach described with the following polyfill, as suggested by the MDN :
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
Alternatively, you might want to consider throwing out elem.matchesSelector
entirely and go with something like this :
function getAncestorBySelector(elem, selector) {
if([].indexOf.call(document.querySelectorAll(selector + ' ' + elem.tagName), elem) === -1) {
// If element is not inside needed element, returning immediately.
return null;
}
// Loop for finding an ancestor element that matches your selector.
}
Both implementations require at least support for querySelectorAll
, which is a feature supported by all modern browsers.
Browser support :
