Подтвердить что ты не робот

JQuery выберите потомков, включая родительский

Рассмотрим следующий 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>

Учитывая элемент DOM obj и выражение, как мне выбрать выбор для любых детей и, возможно, obj? Я ищу что-то похожее на "select descendants", но также включая родителя, если оно соответствует выражению.

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 annoying
var matches = $(".foo", obj);
if ($(obj).is(".foo")) matches = matches.add(obj);
matches.css("color", "red");

Есть ли более элегантное решение?

4b9b3361

Ответ 1

Если я правильно вас понимаю:

$(currentDiv).contents().addBack('.foo').css('color','red');

Для ясности я переименовал "div" в "currentDiv". Это выбирает текущий элемент и все содержащиеся в нем элементы, а затем отфильтровывает те, которые не имеют класса foo, и применяет стиль к остатку, т.е. Те, которые имеют класс foo.

EDIT Небольшая оптимизация

$(currentDiv).find('.foo').addBack('.foo').css('color','red');

ИЗМЕНИТЬ

Этот ответ был обновлен, чтобы включить новые методы jQuery. Первоначально он был

$(currentDiv).find('.foo').andSelf().filter('.foo').css('color','red');

который по-прежнему требуется для jQuery старше 1,8

Ответ 2

jQuery 1.8 представил .addBack(), который принимает селектор в пользу .andSelf(). Таким образом, код tvanfosson становится намного более эффективным, поскольку

$(currentDiv).find(".foo").addBack(".foo").css("color", "red");

Если у вас этого нет, я думаю, что

$(currentDiv).find(".foo").add(currentDiv.filter(".foo")).css("color", "red");

будет довольно эффективным, если не очень красивым.

Ответ 3

Ответ Andrew's был настолько полезен и был наиболее эффективным из всех ответов (начиная с jQuery 1.8), поэтому я сделал это как Sam и превратили его в тривиальный метод расширения jQuery для всех:

Код расширения:

jQuery.fn.findAndSelf = function (selector){
    return this.find(selector).addBack(selector);
};

используйте следующее:

$(function(){
    $('#obj').findAndSelf('.foo').css('color', 'red');
});

JSFiddle: http://jsfiddle.net/BfEwK/

Полный кредит Эндрю за предложение addBack() как лучший вариант (на эту дату). Соответственно поддержали его и предложили всем сделать то же самое.

Ответ 4

Запрет более приятного решения, я создал новую функцию и использую ее вместо $:

var _$ = function(expr, parent){ 
   return $(parent).is(expr) ? $(expr, parent).add(parent) : $(expr, parent); 
}

Ответ 5

Если я не ошибаюсь, не могли бы вы просто сделать следующее?

$("#obj").css("color", "red").find(".foo").css("color", "red");

Найти предполагаемый объект/элемент примените CSS, затем найдите все объекты/элементы в указанном объекте/элементе с указанным селектором, а затем примените CSS к этому?

Ответ 6

Более короткий способ выбора всех элементов-потомков, включая родительский элемент:

$('*', '#parent').addBack();

Это то же самое, что:

$('#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>

Ответ 7

 $('div.foo, div.foo > *').css('color','red');

Основная идея состоит в том, что вы можете разделить разные правила, чтобы они совпадали запятыми. Как и в css. Насколько я знаю, все здесь, завершено jquery и может быть "ORed" разделенным запятой.

Ответ 8

Не делает ли это то, что вы хотите (если я не пойму...)

$(document).ready(function(){
    $("div.foo").css("color", "red");
});