Metoda przechodzenia jQuery find (..) nie obejmuje bieżącego węzła - zaczyna się od elementów podrzędnych bieżącego węzła. Jaki jest najlepszy sposób wywołania operacji wyszukiwania, która zawiera bieżący węzeł w algorytmie dopasowywania? Przeglądając dokumenty, nic od razu na mnie nie wyskakuje.
140
'selector'
dwukrotnego określenia sprawia, że hermetyzacja jest wyjątkowo pożądana. YMMV'selector'
dwa razy (jak wspomniał @ronen), czy nie mógłbyś po prostu użyćobject.parent().find('selector')
??? - Biorąc to pod uwagę, podoba mi się pomysł biblioteki, która robi to za Ciebie.object.parent().find('selector')
obejmuje rodzeństwoobject
i ich potomków.Nie możesz tego zrobić bezpośrednio, najbliższe, o czym przychodzi mi do głowy, to używanie
.andSelf()
i dzwonienie.filter()
, na przykład:$(selector).find(oSelector).andSelf().filter(oSelector) //or... $(selector).find('*').andSelf().filter(oSelector);
Niestety
.andSelf()
nie bierze selektora, który by się przydał.źródło
closest(..)
zawiera bieżący element DOM i wyżej w drzewie, podczas gdy wszystkie metody przechodzenia w dół drzewa, takie jakfind(..)
etc, nie pasują do bieżącego elementu. To tak, jakby zespół jQuery celowo zaimplementował je, aby nie nakładały się, gdy obie operacje są używane razem do pełnego wyszukiwania pionowego.Definiować
$.fn.findSelf = function(selector) { var result = this.find(selector); this.each(function() { if ($(this).is(selector)) { result.add($(this)); } }); return result; };
następnie użyj
zamiast
$find(selector);
Niestety jQuery nie ma tego wbudowanego. Naprawdę dziwne przez tyle lat rozwoju. Moje programy obsługi AJAX nie zostały zastosowane do niektórych najważniejszych elementów z powodu działania .find ().
źródło
filter()
znajduje się tam, co ma większy sens.$('selector').find('otherSelector').add($('selector').filter('otherSelector'))
Możesz zapisać
$('selector')
w zmiennej w celu przyspieszenia. Możesz nawet napisać niestandardową funkcję do tego, jeśli bardzo jej potrzebujesz:$.fn.andFind = function(expr) { return this.find(expr).add(this.filter(expr)); }; $('selector').andFind('otherSelector')
źródło
$('selector').find('otherSelector').add($('otherSelector'))
to równoważne temu, co masz teraz.andSelf()
. Wreszcie,.andFind()
nie filtruje na podstawie wyrażenia, trzeba by.add($(this).filter(expr))
:)$('selector')
zostanie zastąpiona inną metodą uzyskiwania obiektu jQuery (jeśli o to chodziło, nie zaczynając od selektora),add()
poradzi sobie ze wszystkim tak samo, jak$()
może.$('selector')
$('selector').children('filter').closest('.class').last()
Chodziło mi o to, może być ... może być w łańcuchu i nie masz pojęcia, jaki obiekt jest dodawany, więc ogólne rozwiązanie powinno przyjąć poprzedni obiekt tak, jak robi to filtr :)this
jest jakimkolwiek obiektem jQuery, do którego została wywołana wtyczka. Równie dobrze może to być wynikiem łańcucha połączeń.Przyjęta odpowiedź jest bardzo nieefektywna i filtruje zestaw elementów, które są już dopasowane.
//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);
źródło
Jeśli chcesz, aby łańcuch działał poprawnie, użyj poniższego fragmentu.
$.fn.findBack = function(expr) { var r = this.find(expr); if (this.is(expr)) r = r.add(this); return this.pushStack(r); };
Po wywołaniu funkcji end zwraca element #foo.
$('#foo') .findBack('.red') .css('color', 'red') .end() .removeAttr('id');
Bez definiowania dodatkowych wtyczek utkniesz z tym.
$('#foo') .find('.red') .addBack('.red') .css('color', 'red') .end() .end() .removeAttr('id');
źródło
this
jest więcej niż jeden element,this.is()
jest już spełniony, jeśli tylko jeden z nich pasuje.W przypadku, gdy szukasz dokładnie jednego elementu , bieżącego lub wewnątrz niego, możesz użyć:
result = elem.is(selector) ? elem : elem.find(selector);
Jeśli szukasz wielu elementów , możesz użyć:
result = elem.filter(selector).add(elem.find(selector));
Korzystanie z
andSelf
/andBack
jest dość rzadkie, nie wiem dlaczego. Może z powodu problemów z wydajnością, o których wspominali niektórzy faceci.(Teraz zauważyłem, że Tgr podał już to drugie rozwiązanie)
źródło
Wiem, że to stare pytanie, ale jest bardziej poprawny sposób. Jeśli kolejność jest ważna, na przykład gdy dopasowujesz selektor, taki jak
:first
, napisałem małą funkcję, która zwróci dokładnie taki sam wynik, jak gdybyfind()
faktycznie zawierał bieżący zestaw elementów:$.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); };
W żadnym wypadku nie będzie skuteczny, ale to najlepsze, co wymyśliłem, aby utrzymać porządek.
źródło
Myślę, że
andSelf
tego chcesz:obj.find(selector).andSelf()
Zauważ, że to zawsze doda z powrotem bieżący węzeł, niezależnie od tego, czy pasuje do selektora, czy nie.
źródło
Jeśli dokładnie patrzysz na bieżący węzeł (węzły), po prostu to robisz
$(html).filter('selector')
źródło
Próbowałem znaleźć rozwiązanie, które się nie powtarza (tj. Nie wchodząc dwukrotnie w ten sam selektor).
I to małe rozszerzenie jQuery to robi:
jQuery.fn.findWithSelf = function(...args) { return this.pushStack(this.find(...args).add(this.filter(...args))); };
Łączy
find()
(tylko elementy potomne) zfilter()
(tylko bieżącym zestawem) i obsługuje wszystkie argumenty, które zjadają oba.pushStack()
Pozwala na.end()
do pracy zgodnie z oczekiwaniami.Użyj w ten sposób:
$(element).findWithSelf('.target')
źródło
Oto właściwa (ale smutna) prawda:
$(selector).parent().find(oSelector).filter($(selector).find('*'))
http://jsfiddle.net/SergeJcqmn/MeQb8/2/
źródło
$(selector)
się z zestawu we wszystkich przypadkach.