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?

Foi útil?

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

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top