是否有人在DOM api中使用jQuery.closest()等效文件?
看起来Selectors Level 2 draft添加matches()
等同于jQuery.is(),因此原生最接近应该更容易编写。是否已向选择器添加closest()
?
答案 0 :(得分:35)
建立Alnitak的答案。以下是matchesSelector
的工作当前实现,现在是DOM规范中的matches
。
// 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;
}
浏览器支持非常棒:http://caniuse.com/matchesselector
答案 1 :(得分:11)
似乎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
答案 2 :(得分:5)
使用Element.matches()实现此类函数在性能方面似乎不是最佳的,因为看起来match()每次测试父级时都会调用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;
};
}
但请记住,像这样实现的函数在unattached树上不能正常工作(与document.documentElement root分离)
//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中实现的nearest()似乎可以与分离树一起使用
document.documentElement.removeChild(detachedRoot);
child.closestTest("footer"); //null
child.closest("footer"); //<footer>
答案 3 :(得分:3)
考虑到matches
函数,这听起来应该很容易,尽管它还没有被广泛支持:
function closest(elem, selector) {
while (elem) {
if (elem.matches(selector)) {
return elem;
} else {
elem = elem.parentElement;
}
}
return null;
}
问题是,matches
功能未得到适当支持。由于它仍然是一个相对较新的API,因此在Chrome和Safari中可用webkitMatchesSelector
,在Firefox中可用mozMatchesSelector
。
答案 4 :(得分:1)
使用element.closest()我们可以找到最近的祖先匹配选择器。此方法将选择器列表作为参数并返回最近的祖先。根据Rob的评论,这个API可以从chrome 41和FF 35获得。
如whatwg specs 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>
答案 5 :(得分:1)
一点点递归就可以了。
// 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);
};
})();