jQuery выбирает потомков, включая родителя
-
21-08-2019 - |
Вопрос
Рассмотрим следующий 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
?Я ищу что-то похожее на «выбрать потомков», но также включая родителя, если он соответствует выражению.
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");
Есть ли более элегантное решение?
Решение
Если я вас правильно понял:
$(currentDiv).contents().addBack('.foo').css('color','red');
Для ясности я переименовал «div» в «currentDiv».При этом выбирается текущий элемент и все элементы, которые он содержит, а затем отфильтровываются те, у которых нет класса. foo
и применяет стиль к остальным, то есть к тем, у которых есть класс foo
.
РЕДАКТИРОВАТЬ Небольшая оптимизация
$(currentDiv).find('.foo').addBack('.foo').css('color','red');
РЕДАКТИРОВАТЬ
Этот ответ был обновлен, чтобы включить новые методы jQuery.Первоначально это было
$(currentDiv).find('.foo').andSelf().filter('.foo').css('color','red');
который по-прежнему необходим для jQuery старше 1.8.
Другие советы
Представлен jQuery 1.8 .addBack(), который принимает селектор в пользу .andSelf(). Таким образом, код tvanfosson становится намного более эффективным, поскольку
$(currentDiv).find(".foo").addBack(".foo").css("color", "red");
Если бы у тебя этого не было, я думаю, что
$(currentDiv).find(".foo").add(currentDiv.filter(".foo")).css("color", "red");
было бы довольно эффективно, если не очень красиво.
Эндрю был настолько полезным и наиболее эффективным из всех ответов (с JQuery 1.8 и далее), так что я сделал в Сэм предложил и превратил его в тривиальный метод расширения JQuery для каждого использование:
код Extension:
jQuery.fn.findAndSelf = function (selector){
return this.find(selector).addBack(selector);
};
использовать следующим образом:
$(function(){
$('#obj').findAndSelf('.foo').css('color', 'red');
});
JSFiddle: http://jsfiddle.net/BfEwK/
Полный кредит Эндрю предложившего addBack()
как наилучший вариант (по состоянию на эту дату). У upvoted его, соответственно, и предложить всем сделать то же самое.
За исключением более удобного решения, я создал новую функцию и использую ее вместо $:
var _$ = function(expr, parent){
return $(parent).is(expr) ? $(expr, parent).add(parent) : $(expr, parent);
}
Если я не ошибаюсь, не могли бы вы просто сделать следующее?
$("#obj").css("color", "red").find(".foo").css("color", "red");
Найдите предполагаемый объект/элемент, примените CSS, затем найдите все объекты/элементы внутри указанного объекта/элемента с помощью указанного селектора, а затем также примените CSS к нему?
Более короткий способ выбора все элементы-потомки, включая родительский элемент:
$('*', '#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>
Конечно, вы можете изменить универсальный селектор на нужный элемент.
$('.foo', '#parent').addBack();
или
$('#parent').find('.foo').addBack();
Разве это не делает то, что вы хотите (если я не правильно понимаю...)
$(document).ready(function(){
$("div.foo").css("color", "red");
});
$('div.foo, div.foo > *').css('color','red');
Основная идея заключается в том, что вы можете разделять разные правила запятыми.Точно так же, как в CSS.Насколько я знаю все здесь поддерживается jquery и может быть объединен с помощью «ИЛИ» через запятую.