Como obtenho o pai do n-ésimo nível de um elemento no jQuery?

151

Quando eu quero obter, por exemplo, o pai do terceiro nível do elemento que devo escrever $('#element').parent().parent().parent()Existe um método mais ideal para isso?

Artur Keyan
fonte
2
Eu quero dar apenas o número (Nível) e obter elemento, porque o meu elemento não pode ter qualquer ID de calss ou nome
Artur Keyan
1
Se você planeja reutilizar essa funcionalidade, a solução ideal é criar um plug-in jQuery.
precisa saber é o seguinte
3
Veja jsperf.com/jquery-get-3rd-level-parent para algumas comparações de desempenho
a'r
1
Outra boa ferramenta é a função ".closest ()". $ ('li.item'). closest ('div') fornecerá o DIV que é o ancestral mais próximo do li.item. É bom para quando você não sabe quantos níveis estão acima do elemento, mas você sabe o nome da tag / classe / outra coisa.
Graham

Respostas:

267

Como parents () retorna os elementos ancestrais ordenados do mais próximo ao externo, você pode encadeá-lo no eq () :

$('#element').parents().eq(0);  // "Father".
$('#element').parents().eq(2);  // "Great-grandfather".
Frédéric Hamidi
fonte
posso usar esse $ ('# elemento'). parents () [2]? ou deve por com eq (2)
Artur Keyan
1
isto não vai funcionar para várias seleções elemento, uma maneira mais segura seria:$('.element').first().parents().eq(num);
zzzzBov
6
@Arthur, using [2]retornará o elemento DOM subjacente, using eq(2)retornará um objeto jQuery.
Frédéric Hamidi
1
@zzzzBov, é verdade, mas haverá apenas um elemento selecionado no caso do questionador (porque ele corresponde a um ID).
Frédéric Hamidi
Se você pesquisar um ID "#element", ele retornará apenas um único elemento, pois é assim que as pesquisas de ID funcionam, elas retornam o primeiro elemento com esse ID no dom. Se, por outro lado, você fez "div # element" ou um seletor de classe, estaria certo.
Henry
29

Depende de suas necessidades, se você souber qual pai está procurando, poderá usar o seletor .parents ().

EG: http://jsfiddle.net/HenryGarle/Kyp5g/2/

<div id="One">
    <div id="Two">
        <div id="Three">
            <div id="Four">

            </div>
        </div>
    </div>
</div>


var top = $("#Four").parents("#One");

alert($(top).html());

Exemplo usando índice:

//First parent - 2 levels up from #Four
// I.e Selects div#One
var topTwo = $("#Four").parents().eq(2);

alert($(topTwo ).html());
Henry
fonte
Eu agora desta maneira, mas eu quero dar nível
Artur Keyan
3
Leia mais abaixo a resposta e tudo será revelado! (Eu te dei exemplos de nível)
Henry
Isso funciona bem para todos os outros tipos de seletores. Por exemplo, se você quiser a lista de todos os pais e pais de uma determinada turma, isso os retornará.
darksky
8

Você pode dar ao pai de destino um ID ou classe (por exemplo, myParent) e a referência é com $('#element').parents(".myParent")

Joseph Marikle
fonte
Eu quero dar apenas o número e obter elemento, porque o meu elemento não pode ter qualquer ID de calss ou nome
Artur Keyan
6

Uma maneira mais rápida é usar o javascript diretamente, por exemplo.

var parent = $(innerdiv.get(0).parentNode.parentNode.parentNode);

Isso funciona significativamente mais rápido no meu navegador do que encadear .parent()chamadas jQuery .

Consulte: http://jsperf.com/jquery-get-3rd-level-parent

a'r
fonte
Por "significativamente mais rápido", observamos uma ordem de magnitude em termos de diferença de velocidade (executando o jQuery 1.10.1 no Chrome 51). Definitivamente vale a pena implementar se você estiver sintonizando a velocidade.
Iain Fraser
5

Não encontrei nenhuma resposta usando closest() e acho que é a resposta mais simples quando você não sabe quantos níveis estão acima do elemento necessário, portanto, postando uma resposta:
Você pode usar a closest()função combinada com seletores para obter o primeiro elemento correspondente ao percorrer o elemento para cima:

('#element').closest('div')    // returns the innermost 'div' in its parents
('#element').closest('.container')    // returns innermost element with 'container' class among parents
('#element').closest('#foo')    // returns the closest parent with id 'foo'
dinamarquês
fonte
3

É simples. Apenas use

$(selector).parents().eq(0); 

onde 0 é o nível pai (0 é pai, 1 é pai etc)

zatatatata
fonte
3

Basta adicionar o :eq()seletor como este:

$("#element").parents(":eq(2)")

Você acabou de especificar o índice que pai: 0 para pai imediato, 1 para pai principal, ...

MBO
fonte
Dessa forma, é a maneira mais rápida de realizar o trabalho. Aqui está o ponto de referência para provar isso: jsperf.com/jquery-get-element-s-nth-parent
java-homem-script
3

Se você planeja reutilizar essa funcionalidade, a solução ideal é criar um plug-in jQuery:

(function($){
$.fn.nthParent = function(n){
  var $p = $(this);
  while ( n-- >= 0 )
  {
    $p = $p.parent();
  }
  return $p;
};
}(jQuery));

Obviamente, convém estendê-lo para permitir um seletor opcional e outras coisas.

Uma observação: isso usa um 0índice baseado para os pais, nthParent(0)o mesmo que chamar parent(). Se você preferir ter uma 1indexação baseada, usen-- > 0

zzzzBov
fonte
Eu acho que você vai encontrar esta parte mais rápida: var p = 1 + n; while (p--) { $p = $p.parent(); }e se você quer mudar para uma base, Javascript sendo "Falsey" você pode usar: while (n--) { $p = $p.parent();} salvar uma verificação condicional
Mark Schultheiss
@ Mark Schultheiss, não se trata apenas de velocidade, também de confiabilidade. O que acontece com a sua função se alguém ligar ignorantemente nthParent(-2)? Seu exemplo está quebrado.
precisa saber é o seguinte
Ou apenas voltar(function($) { $.fn.nthParent = function(n) { return $(this).parents().eq(n); }; }(jQuery));
Mark Schultheiss
@ Mark Schultheiss, novamente, confiabilidade. Minha função retorna o nthParent para cada elemento na seleção; sua função retorna o enésimo elemento na lista, o parentsqual estará incorreto para seleções com mais de um elemento.
precisa saber é o seguinte
true em relação ao -2, e, como no seu exemplo, usar var p = n >? (1 + n):1; retornaria o primeiro pai nesse caso, em vez de "nada" - ou onde ele interrompe o loop no meu exemplo. ASSIM, provavelmente deveria ser: (function($) { $.fn.nthParent = function(n) { var $p = $(this); if (!(n > -0)) { return $() }; var p = 1 + n; while (p--) { $p = $p.parent(); } return $p; }; }(jQuery)); se você não quiser retornar nada.
Mark Schultheiss
3

Se você tem uma div pai comum, pode usar o link parentsUntil ()

por exemplo: $('#element').parentsUntil('.commonClass')

A vantagem é que você não precisa se lembrar de quantas gerações existem entre esse elemento e o pai comum (definido pela classe comum).

ashishyadaveee11
fonte
1

você também pode usar :

$(this).ancestors().eq(n) 

ex: $(this).ancestors().eq(2)-> o pai do pai de this.

Mouna Cheikhna
fonte
0

Você poderia usar algo como isto:

(function($) {
    $.fn.parentNth = function(n) {
        var el = $(this);
        for(var i = 0; i < n; i++)
            el = el.parent();

        return el;
    };
})(jQuery);

alert($("#foo").parentNth(2).attr("id"));

http://jsfiddle.net/Xeon06/AsNUu/

Alex Turpin
fonte
1
Não é o downvoter, mas esta é provavelmente a pior solução (isto é, ineficiente) aqui.
Zatatatata 17/08/11
0

o uso de eq parece capturar o DOM dinâmico, enquanto o uso de .parent (). parent () parece capturar o DOM que foi carregado inicialmente (se isso for possível).

Eu uso os dois em um elemento que tem classes aplicado em onmouseover. eq mostra as classes enquanto .parent (). parent () não.


fonte
0

Como parents () retorna uma lista, isso também funciona

$('#element').parents()[3];
Fez isso
fonte