有人在 DOM api 中处理jQuery.closest()等价物吗?
看起来Selectors Level 2 草案添加了matches()
等效于jQuery.is(),因此本机最接近应该更容易编写。添加closest()
到选择器出现了吗?
有人在 DOM api 中处理jQuery.closest()等价物吗?
看起来Selectors Level 2 草案添加了matches()
等效于jQuery.is(),因此本机最接近应该更容易编写。添加closest()
到选择器出现了吗?
建立在 Alnitak 的答案之上。matchesSelector
这是目前matches
在 DOM 规范中的工作当前实现。
// get nearest parent element matching selector
function closest(el, selector) {
var matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
while (el) {
if (matchesSelector.call(el, selector)) {
break;
}
el = el.parentElement;
}
return el;
}
似乎 Chrome 40 将带来此处指定的本机element.closest()
方法(http://blog.chromium.org/2014/12/chrome-40-beta-powerful-offline-and.html):https://dom.spec.whatwg .org/#dom-element-closest
用 Element.matches() 实现这样的功能在性能方面似乎不是最优的,因为很明显,matches() 会在您每次测试父母时调用 querySelectorAll() ,而只需一次调用就足以完成这项工作。
这是 MDN 上最接近()的 polyfill。注意对 querySelectorAll() 的一次调用
if (window.Element && !Element.prototype.closest) {
Element.prototype.closest =
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i,
el = this;
do {
i = matches.length;
while (--i >= 0 && matches.item(i) !== el) {};
} while ((i < 0) && (el = el.parentElement));
return el;
};
}
但请记住,像这样实现的功能将无法在未附加的树上正常工作(从 document.documentElement 根分离)
//Element.prototype.closestTest = function(s){...as seen above...};
var detachedRoot = document.createElement("footer");
var child = detachedRoot.appendChild(document.createElement("div"));
detachedRoot.parentElement; //null
child.closestTest("footer"); //null
document.documentElement.append(detachedRoot);
child.closestTest("footer"); //<footer>
虽然在 Firefox 51.0.1 中实现的最接近()似乎与分离树一起工作正常
document.documentElement.removeChild(detachedRoot);
child.closestTest("footer"); //null
child.closest("footer"); //<footer>
考虑到该功能,这听起来应该很容易,matches
尽管尚未得到广泛支持:
function closest(elem, selector) {
while (elem) {
if (elem.matches(selector)) {
return elem;
} else {
elem = elem.parentElement;
}
}
return null;
}
问题是,该matches
功能没有得到适当的支持。由于它仍然是一个相对较新的 API,它可以webkitMatchesSelector
在 Chrome 和 Safari 以及mozMatchesSelector
Firefox 中使用。
使用 element.closest() 我们可以找到最近的祖先匹配选择器。此方法将选择器列表作为参数并返回最近的祖先。根据 Rob 的评论,该 API 将在 chrome 41 和 FF 35 中可用。
正如 whatwg 规范中所解释的那样https://dom.spec.whatwg.org/#dom-element-closest
示例:以下 HTML 将显示警报消息“true”
<html>
<body>
<foo>
<bar>
<a id="a">
<b id="b">
<c id="c"></c>
</b>
</a>
</bar>
</foo>
<script>
var a = document.getElementById('a');
var b = document.getElementById('b');
var c = document.getElementById('c');
alert(c.closest("a, b")==b);
</script>
</body>
</html>
一点递归就可以解决问题。
// get nearest parent element matching selector
var closest = (function() {
var matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
return function closest(el, selector) {
return !el ? null :
matchesSelector.call(el, selector) ? el : closest(el.parentElement, selector);
};
})();