一、Element.matches()
如果元素被指定的选择器字符串选择,Element.matches() 方法返回 true; 否则返回 false。(有一些浏览器使用前缀,在非标准名称 matchesSelector () 下实现了这个方法)
(1) 语法
let result = element.matches(selectorString);
- result 的值为 true 或 false。
- selectorString 是个 css 选择器字符串。
(2)替代方案
对于不支持Element.matches()或 Element.matchesSelector(),但支持document.querySelectorAll() 方法的浏览器,存在以下替代方案
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;
};
}
二、Element.closest()
Element.closest() 方法用来获取:匹配特定选择器且离当前元素最近的祖先元素(也可以是当前元素本身)。如果匹配不到,则返回 null。
(1)语法
var closestElement = targetElement.closest(selectors);
- selectors 是指定的选择器,比如 "p:hover, .toto + q"
- elt 是查询到的祖先元素,也可能是
null
(2)兼容
部分浏览器并不支持Element.closest(),但却支持了element.matches()(或拥有私有前缀,如 IE9+),一个 polyfill 案例
if (!Element.prototype.matches)
Element.prototype.matches =
Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
if (!Element.prototype.closest)
Element.prototype.closest = function (s) {
var el = this;
if (!document.documentElement.contains(el)) return null;
do {
if (el.matches(s)) return el;
el = el.parentElement;
} while (el !== null);
return null;
};
三、组合封装一个根据选择器查找元素的方法
/**
*
* @param { Element } element
* @param { string } selectors
*/
export function getClosestElement(element, selectors) {
if (matchElement(element, selectors)) return element;
if (typeof element.closest === 'function') return element.closest(selectors);
let currentElement;
while ((currentElement = element.parentElement)) {
if (matchElement(currentElement, selectors)) return currentElement;
element = currentElement;
}
return null;
}
/**
*
* @param { Element } element
* @param { string } selectors
*/
export function matchElement(element, selectors) {
if (element.matches) {
return element.matches(selectors);
} else if (element.msMatchesSelector) {
return selectors.msMatchesSelector(selectors);
} else {
return false;
}
}