jQuery - $(this).attr("id") nie działa

0

Witam. Zaczynam właśnie zabawę z jQuery i już schody. Próbuję dla testu zmęczyć kod, który do wszystkich divów wpisze ich id. Poniższy kod nie daje żadnych widocznych rezultatów.
$("div").append($(this).attr("id"));
Natomiast ten poniżej wpisuje do każdego diva id pierwszego z nich.

$.fn.appendId = function() {
  $(this).append($(this).attr("id"));
}

$("div").appendId();

Wyjaśnijcie mi, proszę, bo pojąć nie mogę.

1

each?

0

Dzięki Patryk27. Takie coś działa$("div").each(function () {$(this).append($(this).attr("id"))} );
Czy mam przez to rozumieć, że $(this) mogę używać tylko w połączeniu z each?

2

Tu chodzi nie tyle o znajomość jQuery, co języka JavaScript. A nawet... programowania strukturalnego/proceduralnego. Nie trzeba (nie powinno się!) uczyć na pamięć, gdzie można takich konstrukcji używać, a gdzie nie. To bez sensu!

Wystarczy przeanalizować co się dzieje w programie.

Spójrzmy na tę linijkę:

$("div").append($(this).attr("id"));

Ze zwykłej kolejności wykonywania instrukcji, wspólnej dla bardzo wielu języków -- JavaScriptu, Javy, C... -- wynika, że najpierw wykonywane jest wyrażenie $(this).attr("id"), a dopiero potem jego wartość przekazywana jest do funkcji append().

Dla jasności, powyższy przykład można zapisać tak, wprowadzając zmienną pomocniczą id:

var id = $(this).attr("id");
$("div").append(id);

Najpierw pobieramy ID z elementu, na który wskazuje obecnie referencja this. Co jest tym elementem? Nie wiem. Może nic. Może this akurat wskazuje na window, a więc $(this) zwraca pustą kolekcję jQuery -- która nie ma żadnego atrybutu id. Więc id jest puste/undefined.

Następnie wykonywana jest druga linijka. Do wszystkich divów (bo mamy $("div")...) dodajemy tekst przechowywany w zmiennej id. A że tam jest albo pusty string, albo undefined (nie wiem, nie chce mi się sprawdzać co zwraca attr()), to nic nie jest dopisywane do środka divów.

Czyli: to nie ma jak działać!

Poprawny kod działa zupełnie inaczej...

$("div").each(function () {
  $(this).append($(this).attr("id"));
});

Dla każdego diva, dokładnie raz wywoływana jest funkcja anonimowa (bez nazwy). Wywoływana jest dla pierwszego diva, potem dla drugiego itd. Przy każdym kolejnym wywołaniu, jQuery zapewnia, że referencja this będzie ustawiona na bieżący element div.

Możemy prześledzić co się dokładnie dzieje przy pojedynczym wywołaniu funkcji anonimowej (pamiętaj: będzie tyle takich wywołań ile divów, po jednym dla każdego diva! zmieniała się będzie referencja this).

Ciało funkcji anonimowej ponownie możemy rozpisać tak jak wcześniej, dodając dla wygody zmienną id. Czyli:

  var id = $(this).attr("id");
  $(this).append(id);

Do zmiennej id podstawiamy wartość atrybutu id bieżącego elementu div (bo this wskazuje na bieżący element div). Tym razem jest to to, czego chcemy, bo $(this) przechowuje kolekcję jQuery złożoną z jednego -- aktualnie przetwarzanego -- diva. Wszystko dzięki temu, że this jest ustawione poprawnie.

W zmiennej id mamy więc... id.

Następnie, do bieżącego diva dodajemy to id. Ponownie: korzystamy z właściwie ustawionego this.

Widać różnicę w obu przypadkach?

1 użytkowników online, w tym zalogowanych: 0, gości: 1