Myszka

Dobre słowo na początek:

Jak ważna jest myszka w poruszaniu się po stronach każdy wie. Twórca strony powinien odpowiednio obsługiwać zdarzenia związane z myszką tak, by obsługa jego witryny była jak najbardziej intuicyjna.

Do zdarzeń, które wywołuje kursor myszki zaliczamy:

  • mousedown - przycisk myszki został naciśnięty
  • mouseup - przycisk myszki został puszczony
  • click - przycisk myszki został naciśnięty i puszczony (czyli normalne kliknięcie)
  • dblclick - podwójne kliknięcie - praktycznie nie używane
  • mousemove - kursor porusza się po...
  • mouseover i mouseout - kursor znalazł się i zszedł z obszaru

MouseDown, MouseUp, Click

Zdarzenia te są związane z kliknięciem przyciskiem myszki na dany obiekt.

  1. mousedown - użytkownik nacisnął guzik myszki
  2. mouseup - użytkownik puścił guzik myszki
  3. click - jedno mousedown i jedno mouseup zostało wykryte na danym obiekcie

Istnieje pewna różnica miedzy click i mousedown. Przypuśćmy, że użytkownik nacisnął guzik na odnośniku (hiperłączu), następnie przesunął kursor poza ten odnośnik i puścił przycisk myszki. Odnośnik zarejestrował tylko zdarzenie mousedown. Podobnie - jeżeli użytkownik naciśnie guzik myszki, przesunie kursor na odnośnik i wtedy puści przycisk myszki, to odnośnik zarejestruje tylko mouseup.

W Windows dla większości przycisków stosowane jest zdarzenie click. Sprawdź sam - kliknij na którymś z guzików w prawym górnym rogu dowolnego okna (np. na zamykającym [X]), a następnie nie puszczając przycisku zjedź kursorem z tego guzika... Okno się nie zamknie, bo nie zaistniało zdarzenia click, tylko zdarzenie mousedown.

Ogólna składnia przypisania tych zdarzeń do obiektu jest następująca:


function showMe() {
    console.log(this);
}

document.addEventListener("DOMContentLoaded", function() {
    element.addEventListener('mousedown', showMe);
    element.addEventListener('mouseup', showMe);
    element.addEventListener('click', showMe);
});

Poniżej możesz sprawdzć opisane wyżej przypadki.

MouseOver, MouseMove, MouseOut

Zdarzenia MouseOver, MouseMove i MouseOut służą do sprawdzenia, czy użytkownik najechał kursorem na obiekt, czy się po nim porusza lub czy z niego nim wyjechał.


//włączamy mouseover
element.addEventListener('mouseover', showMe);
//wyłączamy
element.removeEventListener('mouseover', showMe);

//włączamy mousemove
element.addEventListener('mousemove', showMe);
//wyłączamy
element.removeEventListener('mousemove', showMe);


//włączamy mouseout
element.addEventListener('mouseout', showMe);
//wyłączamy
element.removeEventListener('mouseout', showMe);

Bardziej skomplikowany przykład zastosowania tych eventów możecie sprawdzić w balonikach.

Bąbelki

"Nie - no niczym nas nie zaskoczy?" Bynajmniej nie ja. Ale przeglądarki i owszem ;]

Przypuśćmy, że mamy blok:

1

Wszystko standardowo. Po kliknięciu myszką na blok pokazuje się okienko alert().

Co jednak się stanie, gdy nasz blok będzie miał w sobie dwa inne bloki?

1
2
3

<div style="..." id="blok">1
    <div style="...">2
            <div style="...">3</div>
    </div>
</div>

document.getElementById('blok').addEventListener('click', function() {
    alert('Kliknąłeś mnie!')
});

Okazuje się, że zdarzenie przypisane do 1-go bloku odpalane jest też, gdy klikniemy myszką na blok nr 2 i 3 (mimo tego, że bloki te nie mają przypisanego zdarzenia).

Czemu tak się dzieje?

Wszystko za sprawą bąbelków, a raczej bąbelkowego przechwytywania zdarzeń, które jest stosowane dla wszystkich zdarzeń (click, mouseover, mousemove itd.).

Zdarzenia zachowują się tak samo jak bąbelki - lecą ku górze (czyli w stronę kapsla ^^ - u nas w stronę document).

Po kliknięciu na blok nr 3, zdarzenie click będzie wędrować w stronę document, i tym samym spotka na swej drodze blok nr 2 a zaraz potem blok nr 1, który ma przypisane zdarzenie onclick. Tak samo po kliknięciu na blok nr 2, zdarzenie click wędruje do obiektów położonych wyżej (z 2 na 1, następnie do body, i do document). Blok 1 ma przypisane zdarzenie więc je odpala.

Gdyby każdy z bloków miał przypisane zdarzenie click, wówczas po kliknięciu na blok 3, odpalane były by wszystkie zdarzenia!


Aby w IE wyłączyć bąbelkowe zdarzenia, skorzystamy z właściwości window.event.cancelBubble, która ustawiona na true powinna wyłączać "bąbelki". Reszta świata używa metody e.stopPropagation(). Poprawna funkcja wykorzystująca wyżej wymienione właściwości powinna mieć postać jak poniżej:


function stopBubble(e) {
    if (!e) {
        var e = window.event;
    }
    e.cancelBubble = true; 
    if (e.stopPropagation) {
        e.stopPropagation();
    }
}

Należy zauważyć, że wyłączenie bąbelków nie może odbywać się ogólnie (czyli np. w funkcji onload dokumentu). Możemy je wyłączyć tylko lokalnie dla danego zdarzenia:


    document.getElementById('blok31').addEventListener('click', function() {
        alert('Kliknąłeś mnie!')
    });
    document.getElementById('blok32').addEventListener('click', function(e) {
        stopBubble(e);
    });
    document.getElementById('blok33').addEventListener('click', function(e) {
        stopBubble(e);
    });
1
2
3

Target

Javascript udostępnia nam dla zdarzenia właściwość target, która wskazuje nam obiekt, który odpalił to zdarzenie.

e.target:

Co możemy zrobić z taką informacją? Na przykład wykorzystać ją do pozyskania cennych informacji na temat danego obiektu - chociażby jaki to znacznik, jaka jest jego szerokość itp:


e.taget.nodeName; //wskaże nam typ znacznika
e.taget.style.width; //szerokość ustawiona w stylach
1
2
3
Odpalający:

No dobrze, ale skąd mamy wiedzieć, z którego bloku wjechał kursor na blok nr 2? Czy z bloku nr 1 czy z 3?

Na szczęście dla zdarzeń mouseover i mouseout istnieje właściwość relatedTarget, która mówi nam z jakiego elementu myszka przybyła (dla zdarzenia mouseover) i na jaki element zdąża (dla zdarzenia mouseout).

Microsoft jak zwykle ;) stworzył swoje własne właściwości. Tak więc, aby odczytać w IE skąd przybyła myszka - skorzystamy z właściwości fromElement, a by odczytać obiekt, do którego podąża myszka skorzystamy z metody toElement.

Jeżeli chcielibyśmy odczytać obiekt z którego kursor przybył (dla zdarzenia mouseover) skorzystamy z funkcji:


function targetFrom(e) {
    if (!e) var e = window.event;
    if (e.relatedTarget) return e.relatedTarget;
    else if (e.fromElement) return e.fromElement;
}

Jeżeli chcielibyśmy odczytać obiekt, na który kursor myszki podąża (dla zdarzenia mouseout) skorzsytamy z poniższej funkcji:


function targetTo(e) {
    if (!e) var e = window.event;
    if (e.relatedTarget) return e.relatedTarget;
    else if (e.toElement) return e.toElement;
}
1
2
3

zjechałeś kursorem z:

najechałeś kursorem na:

Powyższy przykład odpala te funkcje tylko dla czeronego diva

Pozycja Myszki

Z pobieraniem pozycji myszki niestety sytuacja nie jest tak łatwa jak w powyższych przypadkach. Przeglądarki udostępniają kilkanaście właściwości, które teoretycznie powinny nam dawać pozycję myszki. Jednak w praktyce tylko właściwości screenX i screenY wydają się być "przeznaczone" dla większej liczby przeglądarek. Właściwości te podają pozycję na ekranie użytkownika. Jednakże w większości przypadków dane te są kompletnie nieprzydatne - nigdy nie potrzebujesz wiedzieć, gdzie myszka znajduje się na ekranie. Wolelibyśmy raczej znać jej pozycję na stronie.


function mousePosition(e) {
    var pozX = 0;
    var pozY = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY) {
         pozX = e.pageX;
         pozY = e.pageY;
    } else if (e.clientX || e.clientY) {
         pozX = e.clientX + document.body.scrollLeft;
         pozY = e.clientY + document.body.scrollTop;
    }
    return {pozX,pozY}
}

Który przycisk myszki

Aby odczytać, który przycisk został naciśnięty skorzystamy z właściwości button.

Guziki myszki zostały obdarowane odpowiednimi wartościami:

Dla "normalnego świata" kolejne przyciski mają:

  • lewy guzik - 0
  • środkowy guzik - 1
  • prawy guzik - 2

Microsoft sporządził własną numerację przyciski

  • lewy guzik - 1
  • środkowy guzik - 4
  • prawy guzik - 2

Nie ma co ukrywać - model Microsoftu jest o wiele lepszy od modelu W3C's. W3C zastosowało dla lewego przycisku wartość 0, która powinna oznaczać "nic nie zostało wciśnięte". W tym modelu zastosowanie wartości 0 nie jest za bardzo logiczne.

Poza tym tylko w modelu Microsoftu jesteśmy zdolni do sprawdzenia kombinacji naciśniętych przycisków. Na przykład wartość 5 oznacza "lewy i środkowy przycisk został naciśnięty". No cóż.

Prawy przycisk myszki

Na szczęście bez problemów jesteśmy w stanie sprawdzić czy prawy guzik został naciśnięty.

Aby dokonać takiego sprawdzenia, wystarczy sprawdzić, czy właściwość button równa się 2:


function rightButton(e) {
    var prawyGuzik;
    if (!e) var e = window.event;
    if (e.button) return (e.button==2)?true:false;
    return false;
}