15

有人在 DOM api 中处理jQuery.closest()等价物吗?

看起来Selectors Level 2 草案添加了matches()等效于jQuery.is(),因此本机最接近应该更容易编写。添加closest()到选择器出现了吗?

4

6 回答 6

35

建立在 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;
}

浏览器支持很棒:http ://caniuse.com/matchesselector

于 2013-05-07T23:38:21.903 回答
12

似乎 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

于 2014-12-04T21:51:02.673 回答
7

请参阅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>
于 2017-02-25T15:04:01.127 回答
3

考虑到该功能,这听起来应该很容易,matches尽管尚未得到广泛支持:

function closest(elem, selector) {
    while (elem) {
        if (elem.matches(selector)) {
            return elem;
        } else {
            elem = elem.parentElement;
        }
    }
    return null;
}

问题是,该matches功能没有得到适当的支持。由于它仍然是一个相对较新的 API,它可以webkitMatchesSelector在 Chrome 和 Safari 以及mozMatchesSelectorFirefox 中使用。

于 2013-03-11T00:04:13.510 回答
1

使用 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>
于 2015-01-02T11:41:14.117 回答
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);
    };
})();
于 2015-08-19T13:11:41.610 回答