Element.closest()

Esta tradução está incompleta. Ajude a traduzir este artigo em inglês

Esta é uma tecnologia experimental
Verifique a tabela de compatibilidade entre Navegadores cuidadosamente antes de usar essa funcionalidade em produção.

O método Element.closest() retorna o ancestral mais próximo, em relação ao elemento atual, que possui o seletor fornecido como parâmetro. No caso de o elemento atual possuir o seletor, o mesmo é retornado.  Caso não exista um ancestral o método retorna null.

Sintaxe

var elt = element.closest(selectors); 

Parâmetros

  • selectors é um DOMString contendo uma lista de seletores, por exemplo "p:hover, .toto + q"
  • element é um Element posicionado no início da árvore de elementos a ser percorrida.

Valor retornado

  • elt é um Element selecionado como ancestral mais próximo  do elemento pelo qual se iniciou a pesquisa. O valor retornado pode ser null.

Exceções

  • SyntaxError é lançada caso o parâmetro selectors não seja uma string válida contendo uma lista de seletores.

Exemplo

<article>
  <div id="div-01">Esta é a div-01
    <div id="div-02">Esta é a div-02
      <div id="div-03">Esta é a div-03</div>
    </div>
  </div>
</article>
var el = document.getElementById('div-03');

var r1 = el.closest("#div-02");  
// retorna o elemento com id=div-02

var r2 = el.closest("div div");  
// retorna o ancestral mais próximo que é uma div dentro de uma div, nesse caso div-03 é retornada

var r3 = el.closest("article > div");  
// retorna o ancestral mais próximo que é uma div e tem um article como elemento pai, nesse caso div-01 é retornada

var r4 = el.closest(":not(div)");
// retorna o ancestral mais próximo que não é uma div, neste caso article é retornado

Polyfill

Para navegadores que não suportam Element.closest(), mas possuem suporte para element.matches() (ou um prefixo equivalente, ou seja IE9+), o seguinte polyfill pode ser usado: 

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;
    };

Contudo, se você de fato precisa dar suporte ao IE 8, você pode usar o polyfill abaixo, o qual é lento mas eficaz. Além disso, ele só garante suporte a seletores CSS 2.1 no IE 8 e ainda pode causar picos de lentidão em websites em produção.

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;
    };
}

Especificações

Especificação Status Comentário
DOM
The definition of 'Element.closest()' in that specification.
Padrão em tempo real Definição inicial.

Compatibilidade em navegadores

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
closestChrome Full support 41Edge Full support 15Firefox Full support 35IE No support NoOpera Full support 28Safari Full support 6WebView Android Full support 41Chrome Android Full support 41Firefox Android Full support 35Opera Android Full support 28Safari iOS Full support 9Samsung Internet Android Full support 4.0

Legend

Full support  
Full support
No support  
No support

Veja também