Відповіді:
Для 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);
};
Після виклику функції завершення повертає елемент #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)себе із набору у всіх випадках.