Ответы:
Для jQuery 1.8 и выше вы можете использовать .addBack(). Требуется селектор, поэтому вам не нужно фильтровать результат:
object.find('selector').addBack('selector')
До jQuery 1.8 вы застряли .andSelf()(теперь устарело и удалено), который затем нуждался в фильтрации:
object.find('selector').andSelf().filter('selector')
'selector'дважды делает инкапсуляцию более желательной. YMMV
'selector'дважды (как упоминалось @ronen), не могли бы вы просто использовать object.parent().find('selector')??? - при этом мне нравится идея библиотеки, которая сделает это за вас.
object.parent().find('selector')включает братьев objectи сестер и их потомков.
Вы не можете сделать это напрямую, самое близкое, что я могу придумать, - это использовать .andSelf()и вызывать .filter(), например:
$(selector).find(oSelector).andSelf().filter(oSelector)
//or...
$(selector).find('*').andSelf().filter(oSelector);
К сожалению .andSelf(), селектор не нужен, что было бы удобно.
closest(..)включает текущий элемент DOM и вверх по дереву, тогда как все методы обхода вниз по дереву, такие как и find(..)т.д., не соответствуют текущему элементу. Это как если бы команда jQuery целенаправленно реализовала их для исключения дублирования, когда обе операции используются вместе для полного вертикального поиска.
определять
$.fn.findSelf = function(selector) {
var result = this.find(selector);
this.each(function() {
if ($(this).is(selector)) {
result.add($(this));
}
});
return result;
};
затем используйте
$.findSelf(selector);
вместо того
$find(selector);
К сожалению, в jQuery этого нет. Действительно странно для стольких лет разработки. Мои обработчики AJAX не применялись к некоторым верхним элементам из-за того, как работает .find ().
filter()там, что имеет больше смысла.
$('selector').find('otherSelector').add($('selector').filter('otherSelector'))
Вы можете сохранить $('selector')в переменной для ускорения. Вы даже можете написать для этого собственную функцию, если она вам очень нужна:
$.fn.andFind = function(expr) {
return this.find(expr).add(this.filter(expr));
};
$('selector').andFind('otherSelector')
$('selector').find('otherSelector').add($('otherSelector')), что у вас сейчас эквивалентно .andSelf(). Наконец, .andFind()не фильтрует по выражению, вам нужно .add($(this).filter(expr)):)
$('selector')заменен ли он каким-либо другим методом получения объекта jQuery (если это то, что вы имели в виду, не начиная с селектора), add()может обрабатывать все, что и $()может.
$('selector')может быть $('selector').children('filter').closest('.class').last()... он может быть в цепочке, и вы не знаете, что это за объект, который вы добавляете, поэтому универсальное решение должно принимать предыдущий объект, как и фильтр :)
thisэто какой-либо объект jQuery, к которому был вызван плагин. С таким же успехом это могло быть результатом цепочки вызовов.
Принятый ответ очень неэффективен и фильтрует набор уже сопоставленных элементов.
//find descendants that match the selector
var $selection = $context.find(selector);
//filter the parent/context based on the selector and add it
$selection = $selection.add($context.filter(selector);
Если вы хотите, чтобы цепочка работала правильно, используйте приведенный ниже фрагмент.
$.fn.findBack = function(expr) {
var r = this.find(expr);
if (this.is(expr)) r = r.add(this);
return this.pushStack(r);
};
После вызова функции end возвращает элемент #foo.
$('#foo')
.findBack('.red')
.css('color', 'red')
.end()
.removeAttr('id');
Без определения дополнительных плагинов вы застряли на этом.
$('#foo')
.find('.red')
.addBack('.red')
.css('color', 'red')
.end()
.end()
.removeAttr('id');
thisбольше, чем один элемент this.is(), уже удовлетворен, если только один из них соответствует.
Если вы ищете ровно один элемент , текущий или находящийся внутри него, вы можете использовать:
result = elem.is(selector) ? elem : elem.find(selector);
Если вам нужно несколько элементов, вы можете использовать:
result = elem.filter(selector).add(elem.find(selector));
Использование andSelf/ andBackдовольно редко, не знаю почему. Возможно, из-за проблем с производительностью, о которых до меня говорили некоторые ребята.
(Теперь я заметил, что Tgr уже дал это второе решение)
Я знаю, что это старый вопрос, но есть более правильный способ. Если порядок важен, например, когда вы сопоставляете такой селектор :first, я написал небольшую функцию, которая будет возвращать точно такой же результат, как если бы find()фактически включал текущий набор элементов:
$.fn.findAll = function(selector) {
var $result = $();
for(var i = 0; i < this.length; i++) {
$result = $result.add(this.eq(i).filter(selector));
$result = $result.add(this.eq(i).find(selector));
}
return $result.filter(selector);
};
Это ни в коем случае не будет эффективным, но это лучшее, что я придумал для поддержания надлежащего порядка.
Если вы строго смотрите в текущем узле (ах), вы просто делаете
$(html).filter('selector')
Я пытался найти решение, которое не повторяется (т.е. не вводит один и тот же селектор дважды).
И это крошечное расширение jQuery делает это:
jQuery.fn.findWithSelf = function(...args) {
return this.pushStack(this.find(...args).add(this.filter(...args)));
};
Он объединяет find()(только потомков) с filter()(только текущий набор) и поддерживает любые аргументы, которые оба едят. Это pushStack()позволяет .end()работать должным образом.
Используйте как это:
$(element).findWithSelf('.target')
Вот правильная (но печальная) правда:
$(selector).parent().find(oSelector).filter($(selector).find('*'))
$(selector)само из набора во всех случаях.