Gestione della rotella del mouse in JavaScript

Piccola precisazione:

Il codice qui utilizzato è una rielaborazione e traduzione di quanto pubblicato da Adomas Paltanavicius qui.

Molto gentilmente Adomas ha linkato nel suo sito questo riadattamento.

Problema
Un buon programmatore di solito tende a chiedersi: "E che cacchio, con tutte ste figherie che ci sono oggi (AJAX, Ruby, Script.aculo.us, ecc...) perché non posso usare (roba a caso) nella mia fichissima Web Application?" Non so se voi ve lo chiediate ogni tanto, io sì, anche abbastanza spesso...

La roba a caso di oggi si chiama "Rotella del mouse"

Soluzione
Un tipo lituano ha trovato la soluzione, (già elaborata dal buon Google in Google Maps) e io sono qui a tradurla in italiano e a documentarla un pelo per chiunque abbia voglia di usarla.

In Pratica
La rotella del mouse in qualsiasi browser di solito permette lo scrolling delle pagine... Giusto? Ebbene, la suddetta rotella genera un evento all'interno della finestra, e questo evento può essere letto via JavaScript, con qualche aggiustatina, a seconda del browser utilizzato.

Il valore letto non è numerico, ma si tratta di un "delta" (ovvero una variazione) rispetto al valore precedente. Quindi può essere positivo o negativo. Un immagine, come sempre è meglio di 1000 parole...

Rotella del mouse

Vediamo ora come viene letto l'evento via JavaScript:

// INIZIALIZZAZIONE
if (window.addEventListener) 	// MOZILLA
window.addEventListener('DOMMouseScroll', wheel, false);
 
// IE / OPERA
window.onmousewheel = document.onmousewheel = wheel;

Queste due righe hanno generato il listener per l'evento "movimento della rotella del mouse". Al verificarsi dell'evento viene richiamata la funzione wheel() che è poi la funzione che fa la "magia"

// GESTORE EVENTO "MOVIMENTO ROTELLA"
function wheel(event)
{
// Variabile che conterrà la variazione di movimento
var delta = 0;
 
// INTERNET EXPLORER
if (!event)
event = window.event;
 
// INTERNET EXPLORER E OPERA
if (event.wheelDelta)
{
delta = event.wheelDelta/120;
// IN OPERA 9 IL SEGNO E' INVERTITO
if (window.opera)
delta = -delta;
}
 
// MOZILLA - LUNGA VITA A MOZILLA
else if (event.detail)
{
// DELTA INVERTITO E MULTIPLO DI 3
delta = -event.detail / 3;
}
 
// SE IL DELTA E' DIVERSO DA ZERO ESEGUE LA FUNZIONE HANDLE
if (delta)
handle(delta);
 
// BLOCCA SCROLLING IN PAGINE LUNGHE...
if (event.preventDefault)
event.preventDefault();
 
// RITORNA FALSO
event.returnValue = false;
}

Che abbiamo fatto? Praticamente abbiamo normalizzato i differenti valori restituiti dai diversi browser in modo da ottenere 1 o -1.

Il valore così ottenuto viene passato alla funzione handle() che conterrà le istruzioni da eseguire. Nel nostro caso l'aumentare o il diminuire la dimensione di un testo.

// GESTIONE EVENTO (RIDIMENSIONAMENTO TESTO)
function handle(delta)
{
// Dimensioni testo
var dimensione;
 
if (delta < 0)
{
// Zoom OUT
dimensione = parseInt(document.getElementById("testo").style.fontSize) + 2;
document.getElementById("testo").style.fontSize = dimensione + "px";
}
else
{
// Zoom IN
dimensione = parseInt(document.getElementById("testo").style.fontSize) - 2;
document.getElementById("testo").style.fontSize = dimensione + "px";
}
}

Tutto qua. Niente di più facile. Un esempio, liberamente scaricabile e riadattabile è disponibile qui. Su suggerimento di Adomas ecco un image resizer.

E le pagine lunghe?
Bella domanda. Se usate questo script in una pagina che scrolla, la rotella non permetterà lo scrolling della pagina...

Per gli utenti Firefox
Noi non abbiamo bisogno di questo script di esempio che ho creato... Premendo CTRL mentre si muove la rotella del mouse viene aumentata automaticamente la dimensione del carattere.

Può tornare utile se vogliamo fornire la stessa funzionalità ai "poveracci" che usano Internet Explorer ;)

Compatibilità
Funziona su Firefox 1+, Internet Explorer 5+, Opera, Safari, ecc...

Possibili usi
Zoom di testo, zoom di immagini, scrolling di testo, riordino di liste e qualsiasi idea malsana vi possa venire in mente...

UPDATE!
Andrea Giammarchi ha prodotto un esempio che risolve il problema dello scrolling della pagina. Riporto parte della sua email come spiegazione:

L'evento onmousewheel non ha nulla di diverso da onclick, onmouseover e compagnia bella, questo significa che non è un evento window o document ma un evento qualunque di un Node del DOM (che sia preso per id o tag ha poca importanza purchè sia un elemento del DOM).

Ergo la mia funzione sfrutta onmouseover per attivare su quel solo elemento onmousewheel per poi toglierlo in onmouseout da quell'elemento, quindi non vincola assolutamente lo scroll della pagna fuori dall'elemento :-)

Le potenzialità sono quelle da te descritte nel tuo post del blog, solo che il vincolo della window non esiste ed il fatto che sia un evento compatibile solo con browsers aggiornati gli permette di sfruttare addEventListener o attachEvent per l'onmouseover senza vincolare altri eventuali eventi del DOM sullo stesso elemento (più onmouseover o onmouseout sullo stesso nodo senza problemi.

Trovate il sorgente qui e un'implementazione davvero funzionale qua. Manca quo, ma ci stiamo organizzando.

, , ,
1 Star2 Stars3 Stars4 Stars5 Stars (4 voti, media: 4.5)
Loading ... Loading ...
Condividi

Articoli che potrebbero interessarti

A letto presto stasera
20 Links JavaScript
Tornato…
Il mio strano rapporto con il mouse
Quanto ce l’hai lungo?

16 Commenti per “Gestione della rotella del mouse in JavaScript”

  1. MyAvatars 0.2 Napolux.com :: AJAX, Web 2.0, Blog, PHP, MySQL, JavaScript, xHTML, XML » Usare Google Maps - Prima parte ha detto:

    [...] Visto che tra cani e porci molti (me compreso) ci si trovano bene, oggi vediamo, partendo dal solito principio del “Perché non posso usare (roba a caso) nella mia fichissima Web Application?” citato qui, come poter anche noi utilizzare tutta la potenza di Google Maps, creando da zero una mappa in cui poter inserire dei markers a nostro piacimento. [...]

  2. MyAvatars 0.2 Andrea Giammarchi ha detto:

    grazie per la traduzione, mi permetto di postare anche qui la mia soluzione riadattata che non ha problemi di blocco scroll, spero sia utile.

    esempio: http://www.devpro.it/examples/onmousewheel.html

    sorgente: http://www.devpro.it/javascript_id_134.html

    Saluti

  3. MyAvatars 0.2 Napolux ha detto:

    Fammi capire…

    Praticamente “ascolti” l’evento solo se il mouse è su quella determinata DIV che nel tuo caso ha id “test”.

    Davvero notevole. Posso inserire i riferimenti al tuo esempio e la spiegazione nel post???

  4. MyAvatars 0.2 Andrea Giammarchi ha detto:

    ops …. ho visto dopo la tua risposta, ti ho scritto tutto per email comunque la risposta è si (ma leggi la mail se hai tempo)

    Ciao :-)

  5. MyAvatars 0.2 Napolux ha detto:

    @Andrea Giammarchi

    Fatto! Se ci sono novità fammi un fischio per email ;)

  6. MyAvatars 0.2 Andrea Giammarchi ha detto:

    Una novità c’è … ho aggiunto dipendenze alla funzione che ora è fatta di pochissime linee di codice.

    Siccome il “trick” per l’addEventListener è usato e riusato in non so quante funzioni ho pensato di normalizzare il tutto tramite un oggetto, chiamato DOM (che fantasia …), in grado di aggiungere o rimuovere listener di eventi (uno o più) al fine di non dover “ingigantire” un probabile insieme di scripts con lo stesso controllo per ogni evento che si vuole aggiungere (un pò come hanno fatto in Dojo ma …. hei, Dojo pesa di suo sui 100Kb pacchettizzata … !!!).

    Questo oggetto DOM (http://www.devpro.it/code/135.html) per ora ha solo addEventListener e removeEventListener ma ha la peculiarità di poter essere sfruttato da IE4 a tutti i browsers attuali per gli eventi più comuni o per, in questo caso, l’evento wheel.

    L’oggetto DOM a sua volta sfrutta la JSL (http://www.devpro.it/JSL/), la mia “low-level-lib” preferita, capace di normalizzare tutti i browsers, sempre a partire da IE4, per usare JavaScript 1.6 standard al fine di poter sfruttare senza preoccuparsi di niente prototipi di array come some o filter o altri metodi standard di “oggetti primitivi” presenti solo in JS 1.6, utilissimi per tanti motivi ed in grado di farci creare altre librerie sempre leggere e soprattutto senza preoccuparsi di riscrivere ogni volta “gli stessi tricks” per ogni funzione che vorrebbe sfruttare questa o quella proprietà/metodo.

    Altra caratteristica della JSL è che un domani, quando il 99% dei browsers supporterà almeno JS 1.6 in modo standard, potrà essere esclusa dalla pagina senza problemi, risparmiando i suoi 7Kb di peso, poco influenti se si considerano le potenzialità, ma mai irrisori quando si vuole cercare di risparmiare banda.

    Questo, per concludere, credo sia il “quo” che mancava alla mia soluzione, rinnovo i ringraziamenti per questa traduzione e porgo i saluti :)

  7. MyAvatars 0.2 Napolux ha detto:

    ;)

  8. MyAvatars 0.2 Andrea Giammarchi ha detto:

    Una novità ? Sono idiota :D

    Mi sono incartato con il discorso del blocco che di fatto non esisteva, e siccome onmousewheel è un evento, come ho già detto, di un Elemento e siccome un elemento richiama questo evento solo se il mouse agisce sullo stesso, ho rimosso tutto dalla funzione che ora è più semplice e si spera efficiente che mai :)

    ne parlo nel mio blog:
    http://webreflection.blogspot.com/2006/09/portable-and-rewrote-onmousewheel.html

    qui il nuovo esempio:
    http://www.devpro.it/examples/onmousewheel.html

  9. MyAvatars 0.2 20 Links JavaScript :: Napolux.com ha detto:

    [...] JS Mouse Wheel - ITA [...]

  10. MyAvatars 0.2 pinit ha detto:

    utilissima e bellissima implementazione!

    l’ho usata nel mio piccolo portfolio e funziona benissimo.

  11. MyAvatars 0.2 Napolux ha detto:

    @pinit
    Che bello! Sembra quasi Flash ;)

  12. MyAvatars 0.2 Sam学网页 » Blog Archive » Mouse wheel programming in JavaScript ha detto:

    [...] Italian translation with live demonstration, by Francesco Napoletano. [...]

  13. MyAvatars 0.2 Cl4ud!0 ha detto:

    Ciao, sono Claudio spero leggerai e saprai aiutarmi.
    Da tempo oramai ho un unico e solo problema con l’amato Firefox, non appena lo installo senza che faccio nulla non mi funziona la rotellina del mouse, e non posso neppure scorrere le pagine. Posso farlo solo “manualmente”.
    Solo tempo fa riuscii a risolvere, perchè lo disinstallai e reinstallai, ma poi ho dovuto reinstallarlo nuovamente ultimamente e il problema si è ripresentato.
    Quindi a questo punto credo che il problema sia proprio all’interno della cartella firefox.
    Aspetto una tua risposta, anche via e.mail.
    E W Firefox :mrgreen:

  14. MyAvatars 0.2 Napolux ha detto:

    Purtroppo non saprei come aiutarti… Prova a chiedere sui forum di mozilla italia ;)

  15. MyAvatars 0.2 pinit ha detto:

    piccolo update al post: pare che dalla realease 9.20 di Opera il valore dell’handle non sia più invertito, infatti ora il delta viene gestito come negli altri browsers :smile:

  16. MyAvatars 0.2 Cl4ud!0 ha detto:

    OK, grazie comunque.

Lascia un commento



Chiudi
Invia e-mail