jQuery selecionar descendentes, incluindo o pai
-
21-08-2019 - |
Pergunta
Considere o seguinte HTML:
<div class="foo" id="obj">
I should be changed red
<div class="bar" style="color:black;">
I should not be changed red.
<div class="foo">I should be changed red.</div>
</div>
</div>
Dado um elemento obj
DOM e uma expressão, como faço para ir sobre a seleção de todas as crianças e, possivelmente, obj
? Eu estou procurando algo semelhante a "selecione descendentes", mas também incluindo o pai, se ele corresponde a expressão.
var obj = $("#obj")[0];
//wrong, may include siblings of 'obj'
$(".foo", $(obj).parent()).css("color", "red");
//wrong -- excludes 'obj'
$(".foo", obj).css("color", "red");
//correct way, but it's annoying
var matches = $(".foo", obj);
if ($(obj).is(".foo")) matches = matches.add(obj);
matches.css("color", "red");
Existe uma solução mais elegante para isso?
Solução
Se eu entendi corretamente:
$(currentDiv).contents().addBack('.foo').css('color','red');
Eu rebatizado de "div" para "currentDiv" para maior clareza. Isso seleciona o elemento atual e todos os elementos que ele contém, em seguida, filtra os que não têm classe foo
e aplica o estilo para o restante, ou seja, aqueles que têm classe foo
.
Editar A otimização ligeira
$(currentDiv).find('.foo').addBack('.foo').css('color','red');
Editar
Esta resposta foi atualizado para incorporar métodos do jQuery mais recentes. Foi originalmente
$(currentDiv).find('.foo').andSelf().filter('.foo').css('color','red');
que ainda é necessário para jQuery mais velho do que 1,8
Outras dicas
jQuery 1.8 introduziu href="http://api.jquery.com/addBack/"> .addBack (), que leva um seletor, em favor do código de .andSelf (). Então tvanfosson torna-se muito mais eficiente como
$(currentDiv).find(".foo").addBack(".foo").css("color", "red");
Se você não tem isso, eu acho que
$(currentDiv).find(".foo").add(currentDiv.filter(".foo")).css("color", "red");
seria muito eficiente, se não muito bonita.
resposta de Andrew era tão útil e o mais eficiente de todos as respostas (de jQuery 1.8 em diante), então eu fiz como Sam sugerido e transformou-o em um método de extensão jQuery trivial para que todos possam usar:
código de extensão:
jQuery.fn.findAndSelf = function (selector){
return this.find(selector).addBack(selector);
};
utilização como esta:
$(function(){
$('#obj').findAndSelf('.foo').css('color', 'red');
});
jsFiddle: http://jsfiddle.net/BfEwK/
crédito total a Andrew por sugerir addBack()
como a melhor opção (como nesta data). Tem upvoted-lo em conformidade e sugerir todos fazer o mesmo.
Restrição de uma solução melhor, eu criei uma nova função e usá-lo em vez de $:
var _$ = function(expr, parent){
return $(parent).is(expr) ? $(expr, parent).add(parent) : $(expr, parent);
}
Se não me engano você não poderia apenas fazer o seguinte?
$("#obj").css("color", "red").find(".foo").css("color", "red");
Encontre destina objeto / elemento de aplicar CSS, em seguida, encontrar todos os objetos / elementos dentro do referido objeto / elemento com disse seletor e, em seguida, aplicar o CSS para é assim?
Um caminho mais curto para selecionar todas elementos descendentes, incluindo o elemento pai:
$('*', '#parent').addBack();
O que é o mesmo que:
$('#parent').find('*').addBack();
$('*', '#parent').addBack().css('border', '1px solid #f00');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
<span>Child</span>
<span>Another child</span>
</div>
Claro, você pode mudar o seletor universal para o elemento desejado.
$('.foo', '#parent').addBack();
ou
$('#parent').find('.foo').addBack();
Isso não fazer o que quiser (a menos que eu entenda mal ...)
$(document).ready(function(){
$("div.foo").css("color", "red");
});
$('div.foo, div.foo > *').css('color','red');
A idéia principal é que você pode separar regras diferentes para combinar em por vírgulas. Assim como no css. Tanto quanto eu sei tudo aqui é supoprted por jQuery e pode ser "ORed "by-separando vírgula.