Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [jQuery] $('label').click() wywołuje dwukrotnie callback
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
sowiq
Kiedyś miałem już ten problem, ale obszedłem go trochę inaczej i dałem sobie spokój. Teraz temat powrócił, ale pytam bardziej z ciekawości, bo sytuacja jest dla mnie trochę nielogiczna.

Mam prościutki kod HTML:
  1. <form action="#" method="post">
  2. <label><input type="radio" name="test" value="1" /> test label (click here)</label><br />
  3. <input id="inp2" type="radio" name="test" value="1" /> Another input without label
  4. </form>


A do niego podpięty równie prosty kod JS:
[JAVASCRIPT] pobierz, plaintext
  1. $(document).ready(function(){
  2. $('label').click( function(){
  3. alert('1');
  4. });
  5. $('#inp2').click( function(){
  6. alert('2');
  7. });
  8. });
[JAVASCRIPT] pobierz, plaintext

W działaniu wygląda to tak.

I teraz tak:
- po kliknięciu w pierwsze pole radio pokazuje się alert: 1 - OK.
- po kliknięciu w drugie pole radio pokazuje się alert: 2 - też OK.
- po kliknięciu na napis test label (click here) również pokazuje się alert: 1, ale dwukrotnie. Moje pytanie brzmi - dlaczego tak się dzieje?

Dla bardziej dociekliwych dodam, że change( callback ) nie przyda mi się ze względu na to, że pod IE callback jest wykonywany dopiero w momencie zdjęcia focusa z pola radio.
f1xer
wydaje mi się że to poprawne działanie ponieważ, jak można zauważyć użycie w formularzu label nawet, bez użycia JS powoduje że po kliknięciu w etykietę zaznacza nam się również checkbox, który jest dzieckiem tej etykiety. Inaczej mówiąc wykonują się 2 zdarzenia click. To tylko moja teoria na jej poparcie mam taki oto dowód smile.gif Na twoim przykładzie klikam w label wyskakuje alert ale checkbox NIE JEST ZAZNACZONY kliknę ok w alercie, checkbox się zaznacza i znów alert, ale jeżeli kliknę bezpośrednio w checkbox (nie w etykietę) wówczas alert wykona się tylko raz. Nie mam daru tłumaczenia ale myślę że rozumiesz o co mi chodzi smile.gif

edit:
Co ciekawe taka konstrukcja działa już poprawnie:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  2. "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
  4.  
  5. <title>cosik</title>
  6. <meta http-equiv="content-type"
  7. content="text/html;charset=utf-8" />
  8. <meta http-equiv="Content-Style-Type" content="text/css" />
  9. <script src="jquery-1.3.2.js" type="text/javascript"></script>
  10. <script type="text/javascript">
  11. $(document).ready(function(){
  12. $('label').click( function(){
  13. alert('1');
  14. });
  15. $('#inp2').click( function(){
  16. alert('2');
  17. });
  18. });
  19. </script>
  20. </head>
  21.  
  22. <form action="#" method="post">
  23. <legend>pola tekstowe</legend>
  24. <label for="test">test label (click here)</label><input type="radio" name="test" id="test" value="1" /><br />
  25. <input id="inp2" type="radio" name="test" value="1" /> Another input without label
  26. </form>
  27. </body>
  28. </html>


Przepraszam za chaotyczny styl, ale aż musiałem oderwać się od projektu żeby się tym pobawić smile.gif
sowiq
Cytat(f1xer @ 28.08.2009, 02:39:18 ) *
wydaje mi się że to poprawne działanie ponieważ, jak można zauważyć użycie w formularzu label nawet, bez użycia JS powoduje że po kliknięciu w etykietę zaznacza nam się również checkbox, który jest dzieckiem tej etykiety.
Wszystko ładnie, pięknie, ale pierwsze pole radio nie ma przypisanego zdarzenia onclick smile.gif

Jeśli zrobię sobie tak:
  1. <div><span></span></div>
oraz:
[JAVASCRIPT] pobierz, plaintext
  1. $('div').click( function(){ alert(''); });
[JAVASCRIPT] pobierz, plaintext
to idąc Twoim tokiem rozumowania alert również powinien pokazać się dwa razy, a tak się nie dzieje. Musiałbym przypisać zdarzenie również do elementu <span />.

Chyba że pole <label /> działa tak, że po kliknięciu w nie przeglądarka sama wywołuje akcję kliknięcia na elemencie w środku, bo programistom było łatwiej (bo np. taka akcja była już oprogramowana).
wookieb
  1. $('label').click( function(){
  2. alert('1');
  3. return false;
  4. });
A dlaczego tak się dzieje to dokladnie nie wiem. Prawdopodobnie chodzi o bąbelkowanie eventów.
sowiq
Cytat(wookieb @ 28.08.2009, 09:30:53 ) *
Prawdopodobnie chodzi o bąbelkowanie eventów.
Cały szkopuł polega na tym, że takie zachowanie można zaobserwować tylko dla <label />. Dodałem dla przykładu <div /> z dwoma <span /> wewnątrz. Pierwszy <span /> nie ma przypisanej akcji, więc po kliknięciu wyświetla się tylko jeden alert. Identycznie powinno być w przypadku pierwszego pola radio.

http://sowiq.net/jquery/
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.