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 p
s, 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
}
});
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.
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;
}
Sie können die Funktion index()
verwenden:
$('p').each(function(){
var index = $(this).index();
if(index > $("#first").index() && index < $("#second").index()) {
// do stuff
}
});
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
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')
}
});
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;
}
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:
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.
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.