[jQuery] Alle Elemente aus Selector ansprechen

kuhlmaehn

Erfahrenes Mitglied
Hi,
ich frag mich, ob es eine Möglichkeit gibt alle Elemente, die von einem Selector betroffen sind anzusprechen. Also so, dass das zeite "#hu > .ha > li" nicht mehr nötig wäre:
Code:
$("#hu > .ha > li").click(function()
{
  $("#hu > .ha > li").removeClass(...);
  $(this).addClass(...);
}
So hätte ich das z.B. gerne:
Code:
$("#hu > .ha > li").click(function()
{
  $(all).removeClass(...);
  $(this).addClass(...);
}
Das einzige was mir einfällt, ist vorher eine Variable zu definieren:
Code:
var all = $("#hu > .ha > li");
all.click(function()
{
  $(all).removeClass(...);
  $(this).addClass(...);
}
Aber vielleicht gibt es da ja schon was jQuery internes. Danke!
 
Ich persönlich benutze immer folgendes

Javascript:
var all = $("#hu > .ha > li").click(function()
{
    all.removeClass(...);
    $(this).addClass(...);
});

Also im Prinzip die Kurzform deiner Variablen-Version. Das ist auf jedenfalls wesentlich besser als den Selektor nochmal auszuwerten.
 
Zuletzt bearbeitet:
Hey, danke. Ich kann es gerade nicht testen aber müsste dann die Variable "all" nicht eigentlich den ganzen Click-Handler enthalten? Das wirkt dann irgendwie ein bisschen wie eine endlose Rekursion auf mich, weil "all.removeClass(...);" ja jedes mal wieder sich selbst aufruft!?
Ich glaub dir aber das es funktioniert, aber warum? :)
Das ist dann natürlich eine saubere Lösung, die ich dann auch in Zukunft so machen werden :)
 
Die meisten jQuery Funktionen liefern das Objekt selbst als Ergebnis zurück. Deshalb sind ja solche Sachen hier möglich:

Javascript:
$('div').show().fadeTo('slow', 0.4).html('Loading...').load('ajax.php');

oder

Javascript:
var all = $("#hu > .ha > li")
	.click(function() {
		all.removeClass('a');
		$(this).addClass('a');
	})
	.hover(function() {
		//...
	}, function() {
		//...
	})
	.fadeTo('fast', 0.75);

Edit: Wenn man jetzt noch "end" dazu nimmt, kann man das ganze auf die Spitze treiben.

Javascript:
var all = $("#hu > .ha > li")
	.show()
	.find('.foo')
	.hide()
	.end()
	.addClass('bar');

Alle Element die "#hu > .ha > li" sind UND ".foo" sind jetzt unsichtbar aber die anderen sind sichtbar. Außerdem habe alle "#hu > .ha > li" noch die Klasse "bar" verpasst bekommen. "all" enthällt ALLE "#hu > .ha > li".

http://api.jquery.com/end/
 
Zuletzt bearbeitet:
Alles klar, danke!
Ich war mir halt nicht ganz sicher, op die Zuweisung zu "all" nach dem Chaining passiert oder das Gleich sich direkt auf das "$("#hu > .ha > li")" bezieht und das Chaining dann mit dem Wert von "all" fortgesetzt wird.
Also:
var all = $("#hu > .ha > li").click(function(){all.removeClass(...); $(this).addClass(...);});

oder so:
var all = $("#hu > .ha > li").click(function(){all.removeClass(...); $(this).addClass(...);});

Aber dann muss es wohl zweiteres sein (oder ich hab irgendwas grundlegend falsch verstanden ;))
 
Es ist definitiv ersteres, denn der "." Operator bindet stärker als der Zuweisungsoperator ("="). Es wird auf jedenfall zuerst der gesamte rechte Ausdruck ausgewertet.

Aber:
Die beiden grünen Ausdrücke haben den exakt gleichen Wert.

var all = $("#hu > .ha > li").click(function(){all.removeClass(...); $(this).addClass(...);});

var all = $("#hu > .ha > li").click(function(){all.removeClass(...); $(this).addClass(...);});

Javascript:
var all = $("#hu > .ha > li");

//True, weil das geiche Objekt zurückgegeben wird
alert(all === all.click(function() {}));

//False, weil zwei Objekte angelegt werden
alert($("#hu > .ha > li") === $("#hu > .ha > li").click(function() {}));
 
Mh dann versteh ich aber nicht, wieso z.B. im obigen Beispiel
Code:
var all = $("#hu > .ha > li").click(function()
{
    all.removeClass(...);
    $(this).addClass(...);
});
"all" in der inneren Funktion schon vorhanden ist bzw. verwendet werden kann, obwohl die Zuweisung eigentlich noch gar nicht stattgefunden hat?!

Das mit dem exakt gleichen Wert aus Beispiel hier drüber gilz aber auch nur, wenn nicht die auswahl z.B. mit find() oder children() oder so weiter eingeschränkt wird oder?
 
Der click-Handler, in welchem du die Variable verwendest, existiert aber doch erst, sobald der Ausdruck ausgewertet ist. Er ist doch ein Teil des Ausdrucks. Du führst den ja nicht sofort aus, sondern definierst ihn nur.

Das mit dem exakt gleichen Wert aus Beispiel hier drüber gilz aber auch nur, wenn nicht die auswahl z.B. mit find() oder children() oder so weiter eingeschränkt wird oder?

Ja.
 
Danke, den zweiten Teil habe ich dann soweit begriffen aber beim ersten hat es noch nicht klick gemacht. Hoffentlich hast du noch etwas Geduld :)
Wenn man dann jetzt davon ausgeht, dass die Javascript-Engine den Ausdruck auswertet, dann müsste sich doch aber folgendes ergeben:

var all = $("#hu > .ha > li").click(function()
{
($("#hu > .ha > li").click(function()
{
($("#hu > .ha > li").click(function()
{
($("#hu > .ha > li").click(function()
{
(...).removeClass(...);
$(this).addClass(...);
});)
.removeClass(...);
$(this).addClass(...);
});)
.removeClass(...);
$(this).addClass(...);
});)
.removeClass(...);
$(this).addClass(...);
});

Also das "all" wird jedes mal ersetzt, durch den gesamten Ausdruck, der jedoch wieder ein "all" enthält, welches dann wieder ersetzt wird usw.
Oder wo liegt hier der Denkfehler?
 
Es wird zur Laufzeit das ausgewertet, was dran ist. Also spielt das all innerhalb der Funktion erst dann eine Rolle, wenn diese ausgeführt wird. Deshalb ist auch sowas kein Problem:

Javascript:
function foobar() {
	alert(x);
}

var x = 'foo';

foobar();

Das allerdings geht nicht (bzw. x ist dann undefiniert)

Javascript:
function foobar() {
	alert(x);
}

foobar();

var x = 'foo';

Und hier ist x zuerst undefiniert und danach foo.

Javascript:
function foobar() {
	alert(x);
}

foobar();

var x = 'foo';

foobar();
 
Zurück