Rekursion in jQuery.find () für einen Selektor überspringen?

TL; DR:Wie bekomme ich eine Aktion wie find (), aber blockiere Traversal (nicht Punkt, nur Überspringen) für einen bestimmten Selektor?

ANTWORTEN:$(Any).find(Selector).not( $(Any).find(Mask).find(Selector) )

Es gab viele wirklich großartige Antworten. Ich wünschte, ich könnte die Kopfgeldpunkte mehr verteilen. Vielleicht sollte ich als Reaktion auf einige dieser Fragen etwa 50 Punkte Kopfgeld machen. P Ich wähleKarl-André Gagnon weil diese Antwort findExclude in einer, etwas langen, Zeile unnötig machen konnte. Während dies drei find-Aufrufe und einen schweren not-Filter verwendet, kann jQuery in den meisten Situationen eine sehr schnelle Implementierung verwenden, bei der der Durchlauf für die meisten find () s übersprungen wird.

Besonders gute Antworten sind nachfolgend aufgeführt:

Falsarella: Gute Besserung anmeine Lösung, findExclude (), am besten in vielen Situationen

Zbyszek: Eine filterbasierte Lösung ähnlich der von Falsarella, die auch eine gute Effizienz aufweist

Justin: Eine völlig andere, aber überschaubare und funktionale Lösung für die zugrunde liegenden Probleme

Jedes von diesen hat seine eigenen einzigartigen Vorzüge und verdient eine Erwähnung.

Ich muss vollständig in ein Element absteigen und Selektoren vergleichen, wobei alle übereinstimmenden Selektoren als Array zurückgegeben werden, aber ich muss in den Baum absteigen, wenn ein anderer Selektor angetroffen wird.

Bearbeiten: Ersetzen des ursprünglichen Codebeispiels durch eines von meiner Site

Dies ist für ein Nachrichtenforum, in dem möglicherweise Antwortnachrichtengruppen in einer Nachricht verschachtelt sind.
Beachten Sie jedoch, dass wir die Nachrichten- oder Inhaltsklassen nicht verwenden können, da das Skript auch für andere Komponenten außerhalb des Forums verwendet wird. NurInterfaceGroup, Interface undcontrols Klassen sind möglicherweise nützlich - und vorzugsweise nur Interface und Steuerelemente.

Interagiere mit dem Code und sieh ihn dir in JS Fiddle an, danke Dave A, hier Klicken Sie auf die Schaltflächen, während Sie eine JavaScript-Konsole anzeigen, um festzustellen, dass die Steuerelementklasse an eine zusätzliche Zeit pro Ebene der .Interface-Verschachtelung gebunden ist.

Visual A, Forum Layout Struktur:

    <li class="InterfaceGroup">
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup"> ... condensed ...</li>
        </ul>
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
        </ul>
        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup"> ... condensed ...</li>
        </ul>

    </li>

Innerhalb von jedem<li class="InterfaceGroup"> Es kann eine beliebige Anzahl von Wiederholungen derselben Struktur geben (jede Gruppe ist ein Nachrichtenthread) und / oder eine tiefere Verschachtelung, wie z.

    <li class="InterfaceGroup">

        <ul class="Interface Message" data-role="MessagePost" >
            <li class="instance"> ... condensed ... </li>
            <li class="InterfaceGroup">

                <ul class="Interface Message" data-role="MessagePost" >
                    <li class="instance"> ... condensed ... </li>
                    <li class="InterfaceGroup"> ... condensed ...</li>
                </ul>
            </li>
        </ul>
    </li>

Innerhalb von jedem<li class="instance"> ... </li> Es gibt beliebige Orte, an denen von einem anderen Team entschieden wirdclass="controls" möglicherweise angezeigt und ein Ereignislistener sollte gebunden werden. Obwohl diese Nachrichten enthalten, strukturieren andere Komponenten ihr Markup willkürlich, haben es aber immer.controls Innen.Interface, die in einem. gesammelt werden.InterfaceGroupEine Version des inneren Inhalts mit reduzierter Komplexität (für Forenbeiträge) finden Sie weiter unten als Referenz.

Visual B, Nachrichteninhalt mit Steuerelementklasse:

<ul class="Interface Message" data-role="MessagePost" >
    <li class="instance">
      <ul class="profile"> ...condensed, nothing clickable...</ul>
      <ul class="contents">
        <li class="heading"><h3>Hi there!</h3></li>
        <li class="body"><article>TEST Message here</article></li>
        <li class="vote controls">
          <button class="up" data-role="VoteUp" ><i class="fa fa-caret-up"> </i><br/>1</button>
          <button class="down" data-role="VoteDown" >0<br/><i class="fa fa-caret-down"> </i></button>
        </li>
        <li class="social controls">
          <button class="reply-btn" data-role="ReplyButton" >Reply</button>
        </li>
      </ul>
    </li>
    <li class="InterfaceGroup" >    <!-- NESTING OCCURRED -->
      <ul class="Interface Message" data-role="MessagePost" >
          <li class="instance">... condensed ... </li>
          <li class="InterfaceGroup" >... condensed ... </li>
      </ul>
   </li>
</ul>

Wir können nur an Kontrollen binden, die es sindinnerhalb einer Interface-Klasse, instance kann oder kann nicht existieren, aber Interface wird.Events sprudeln zu.controls Elemente und haben einen Verweis auf die.Interface was sie hält..

Also versuche ich es$('.Interface').each( bind to any .controls not inside a deeper .Interface )

Das ist der schwierige Teil, weil

.Interface .controls wird das gleiche auswählen.control mehrmals in der .each ().not ('. Interface .Interface .controls') bricht Steuerelemente in tieferen Verschachtelungen ab

Wie kann ich das mit jQuery.find () oder einer ähnlichen jQuery-Methode machen?

Ich habe darüber nachgedacht, vielleicht Kinder ohne Selektor zu benutzenkönnten Arbeit undkönnten Ich mache dasselbe wie unter der Haube, aber ich bin mir nicht so sicher, ob es tatsächlich eine schreckliche Leistung bringt oder nicht. Trotzdem ist eine Antwort, bei der Kinder tatsächlich wiederkehren, akzeptabel.

UPDATE: Ursprünglich habe ich aus Gründen der Kürze versucht, ein Pseudo-Beispiel zu verwenden, aber hoffentlich hilft das Vorhandensein einer Forum-Struktur dabei, das Problem zu klären, da es sich um natürlich verschachtelte Strukturen handelt. Unten poste ich auch teilweise Javascript als Referenz, Zeile zwei der Init-Funktion ist am wichtigsten.

Reduzierter JavaScript-Teil:

var Interface=function()
{
    $elf=this;

    $elf.call=
    {
        init:function(Markup)
        {
            $elf.Interface = Markup;
            $elf.Controls = $(Markup).find('.controls').not('.Interface .controls');
            $elf.Controls.on('click mouseenter mouseleave', function(event){ $elf.call.events(event); });
            return $elf;
        },
        events:function(e)
        {
            var classlist = e.target.className.split(/\s+/), c=0, L=0;
            var role = $(e.target).data('role');

            if(e.type == 'click')
            {
                CurrentControl=$(e.target).closest('[data-role]')[0];
                role = $(CurrentControl).data('role');

                switch(role)
                {
                    case 'ReplyButton':console.log('Reply clicked'); break;
                    case 'VoteUp':console.log('Up vote clicked'); break;
                    case 'VoteDown':console.log('Down vote clicked'); break;
                    default: break;
                }
            }
        }
    }
};

$(document).ready( function()
{
    $('.Interface').each(function(instance, Markup)
    {
        Markup.Interface=new Interface().call.init(Markup);
    });
} );

Antworten auf die Frage(8)

Ihre Antwort auf die Frage