web-dev-qa-db-de.com

Prüfen Sie, ob das Element vor oder nach einem anderen Element in jQuery steht

Nehmen wir an, ich habe diese Auszeichnung

<h3 id="first">First</h3>
<p>Hi</p>
<p>Hello</p>
<h3 id="second">Second</h3>
<p>Bye</p>
<p>Goodbye</p>

Wie kann ich programmgesteuert überprüfen, ob ein Element, z. B. eines der Variablen ps, nach dem ersten h3 und vor dem zweiten h3 mit jQuery liegt?

Ich versuche so etwas zu tun:

$(p).each(function(){
   if($(this).isAfter("#first") && $(this).isBefore("#second")) {
     // do stuff
   }
});
43
Peter Olson

Die Lösung von Rocket funktioniert gut, wenn sel ein echter Selektor ist. Wenn Sie jedoch ein Jquery-Objekt übergeben, funktioniert es nicht.

Wenn Sie ein Plugin wünschen, das sowohl mit Selektoren als auch mit Jquery-Objekten funktioniert, verwenden Sie stattdessen meine etwas modifizierte Version:

(function($) {
    $.fn.isAfter = function(sel){
        return this.prevAll().filter(sel).length !== 0;
    };

    $.fn.isBefore= function(sel){
        return this.nextAll().filter(sel).length !== 0;
    };
})(jQuery);

Ein dickes Lob an Rocket für die Originallösung.

49
Marco Fucci

Um herauszufinden, ob ein Element hinter einem anderen Element liegt, können Sie mit prev() oder prevAll() das vorherige Element bzw. die vorherigen Elemente abrufen und prüfen, ob es übereinstimmt.

Und um zu sehen, ob ein Element vor einem anderen Element liegt, können Sie mit next() oder nextAll() das nächste (n) Element (e) abrufen und sehen, ob es passt.

$.fn.isAfter = function(sel){
  return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
  return this.nextAll(sel).length !== 0;
}

DEMO: http://jsfiddle.net/bk4k7/

46
Rocket Hazmat

Sie können die Funktion index() verwenden:

$('p').each(function(){
   var index = $(this).index();
   if(index > $("#first").index() && index < $("#second").index()) {
     // do stuff
   }
});
22
Dennis

Ich habe eine allgemeine isAfter-Funktion implementiert, die die Tiefe und den DOM-Baum berücksichtigt und korrekt feststellen kann, ob a hinter b liegt, auch wenn sie sich in 2 verschiedenen Teilbäumen befinden:

<div>
  <div>
    <p class="first">I come first</p>
  </div>
</div>

<div>
  <div>
    <p class="second">I come second</p>
  </div>
</div>

sie finden es in meinem GitHub-Repository . Ich würde mich über Ihr Feedback zum Code freuen

2
Arash Dalir

Hier ist eine Geige

$('p').each(function() {
    previousH3 = $(this).prevAll('h3');
    nextH3 = $(this).nextAll('h3');

    if (previousH3.length > 0 && nextH3.length > 0) {
        $(this).css('color', 'red')
    }

});
2
Amin Eshaq

Die Antwort:

$.fn.isAfter = function(sel){
    return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
    return this.nextAll(sel).length !== 0;
}

Wurden alle vorherigen Elemente oder nächsten Elemente unabhängig vom Selektor (sel) ausgewählt, so habe ich die folgenden Änderungen vorgenommen, um Elemente auf Klassenbasis auszuwählen:

$.fn.isAfter = function(sel){
    sel = "." + sel.attr("class").replace(/ /g, ".");

    return this.prevAll(sel).length !== 0;
}
$.fn.isBefore= function(sel){
    sel = "." + sel.attr("class").replace(/ /g, ".");

    return this.nextAll(sel).length !== 0;
}
1
Peter

Die akzeptierte Antwort funktioniert nur, wenn sich die Elemente auf derselben Ebene befinden. Ein Ansatz, um es zu lösen, wenn Sie herausfinden möchten, welches Element unabhängig von der Ebene das erste ist, ist:

  1. Legen Sie für jedes Element ein temporäres Attribut mit demselben Wert fest
  2. Verwenden Sie einen JQuery-Selektor, um das erste Element mit diesem Attributwert zu finden
0
Joe

In Anbetracht der Antwort von Rocket benutze ich .index() wie folgt:

$.fn.isAfter = function(sel){
    return $(this).index() > $(sel).index();
};
$.fn.isBefore= function(sel){
    return $(this).index() < $(sel).index();
};

Es scheint klarer für das Lesen/Verstehen und funktioniert perfekt bei der Zeilenauswahl.

0
Sergei Dubinin

Die vorherigen Antworten funktionieren gut, wenn die fraglichen Elemente Geschwister sind (was sie in der ursprünglichen Frage sind), aber eine allgemeinere Lösung würde das folgende Szenario in Betracht ziehen:

<div id="top">    
    <div>
        <div>
           <h3 id="first">First</h3>
           <p>Hi</p>
           <p>Hello</p>
        </div>
    </div>
    <div>
        <h3 id="second">Second</h3>
        <p>Bye</p>
        <p>Goodbye</p>
    </div>
</div>

Eine allgemeinere Lösung wäre:

$.extend($.fn, {
    isBefore: function(sel, context) {
        // Get all element within the context.
        var all = $(context || document).find("*");
        return all.index(this[0]) < all.index($(sel));
    },

    isAfter: function(sel, context) {
        return !this.isBefore(sel, context);
    }
});

Wobei "Kontext" ein optionaler Parameter ist, der lediglich den Suchbereich für jQuery begrenzt, um die Leistung zu verbessern. Ich habe keine Tests durchgeführt, aber "Kontext" ist wahrscheinlich unnötig, da $ ("*") qualitativ schnell ausgeführt wird. Beachten Sie auch, dass index () -1 zurückgibt, wenn sich das Element nicht im Kontext befindet.

$("#first").isBefore("#second");  
// Gives the same result as
$("#first").isBefore("#second", "#top");

Natürlich wird davon ausgegangen, dass Sie mit "vor" und "nach" die Reihenfolge im Dokumentmodell meinen. Wenn Sie sich Sorgen um ihre relativen Positionen auf der Anzeige machen, möchten Sie die Anzeigekoordinaten der Elemente in Bezug auf das Dokument als "relative", "feste" und "absolute" CSS-Positionen untersuchen.

0
moomoo