2012-10-04 8 views
9

Provo a creare uno script di evento rotellina, ma ottengo alcuni problemi dal momento che sto usando un Apple Magic Mouse e la sua funzione continua-su-scorrimento .Come verificare ogni nuovo scorrimento ed evitare il problema dei mouse Apple (effetto a scorrimento multiplo)

io voglio fare questo http://jsfiddle.net/Sg8JQ/ (da jQuery Tools Scrollable with Mousewheel - scroll ONE position and stop, utilizzando http://brandonaaron.net/code/mousewheel/demos), ma voglio una breve animazione (come 250 ms) durante lo scorrimento di scatole, e la capacità di andare throught più caselle quando si scorre più volte nel corso di un'animazione. (Se si scorre, l'animazione inizia a scorrere alla seconda casella, ma se si scorre di nuovo, voglio andare alla terza e se scorrono due volte, alla quarta ecc.)

Ho pensato per la prima volta a stopPropagation/preventDefault/return false; potrebbe "arrestare" la velocità della rotellina del mouse (e il var delta) - così posso contare il numero di nuovi eventi di scorrimento (magari con un timer) -, ma nessuno di loro lo fa.

Idee?

MODIFICA: se si tenta di scorrere in Google Calendari con questi mouse, vengono cambiati diversi calendari, non solo uno. Sembra che non possano aggiustarlo neanche.

MODIFICA 2: Ho pensato di separare la rotellina del mouse e legarlo di nuovo dopo aver fermato l'ascoltatore della rotellina della ruota (e non ascoltare la fine dell'inerzia). Io non l'ho fatto.

EDIT 3: ha provato a lavorare con le date (grazie a this post), non è ottimale, ma meglio di niente http://jsfiddle.net/eZ6KE/

+1

Questo non sarà un problema solo su Magic Topi, ma su tutti i sistemi con lo scrolling inerziale (cioè tutti i Mac recenti, molti PC più recenti), il tuo suggerimento sul conteggio degli eventi di scorrimento sembra ragionevole e potresti doverlo implementare da solo. –

+0

Sì hai ragione, questo è un problema inerziale (e sto sperimentando questo con il mio Magic Mouse). Se il conteggio degli eventi di scorrimento sembra una buona soluzione, non ho idea di come eseguirlo. Ho provato a verificare - ad ogni evento di scroll (chiamato ogni volta durante l'inerzia) se il delta precedente era> o <, ma la curva non è lineare, è elastica sul mio test. Qualche idea ? (Grazie comunque!) – Joan

+0

Possibile correzione: https://github.com/brandonaaron/jquery-mousewheel/issues/36 (non ancora testato). – Joan

risposta

0

Ho avuto un problema simile sul mio sito e dopo molti tentativi falliti, ho scritto una funzione che offset totale calcolato della casella selezionata e avvio dell'animazione. Sembrava questo:

function getOffset() { 
    var offset = 0; 
    $("#bio-content").children(".active").prevAll().each(function (i) { 
     offset += $(this)[0].scrollHeight; 
    }); 
    offset += $("#bio-content").children(".active")[0].scrollHeight; 

    return offset; 
} 

var offset = getOffset(); 
$('#bio-content').stop().animate({ 
      scrollTop: offset 
}, animationTime); 

Spero che ti dia un'idea di come ottenere ciò che desideri.

+0

Devo essere frainteso ma non vedo come possa risolvere il problema ... – Joan

+0

Da quello che ho capito, vuoi essere in grado di scorrere di nuovo mentre sta accadendo l'animazione. Ho ragione? Se è così, allora quello che devi fare è trovare l'offset di quella casella particolare, che vuoi scorrere, fermare l'animazione in corso e avviarne una nuova, che scorrerà fino all'offset desiderato. – Dygestor

+0

In realtà, il vero problema è l'impossibilità di fermare lo scroll di inerzia una volta che abbiamo lanciato un'animazione. Essere in grado di lanciarlo di nuovo (una volta che abbiamo fermato l'inerzia e se l'utente scorre di nuovo) è secondario. Nel tuo esempio come il mio, l'animazione verrà chiamata più volte per uno scorrimento a causa dell'inerzia. – Joan

0

si può provare rilevare quando la ruota smette di muoversi, ma sarebbe aggiungere un ritardo al tempo di risposta

$(document).mousewheel(function() { 
    clearTimeout($.data(this, 'timer')); 
    $.data(this, 'timer', setTimeout(function() { 
    alert("Haven't scrolled in 250ms!"); 
    //do something 
    }, 250)); 
}); 

fonte: jquery mousewheel: detecting when the wheel stops?

o implementare bandiere evitando l'inizio di una nuova animazione

var isAnimating=false; 

$(document).bind("mousewheel DOMMouseScroll MozMousePixelScroll", function(event, delta) { 
    event.preventDefault(); 
    if (isAnimating) return; 
    navigateTo(destination); 
}); 

function navigateTo(destination){ 
    isAnimating = true; 
    $('html,body').stop().animate({scrollTop: destination},{complete:function(){isAnimating=false;}}); 
} 
1

Il modo migliore è utilizzare un timeout e controllare all'interno del listener se il timeout è ancora attivo:

var timeout = null; 
var speed = 100; //ms 
var canScroll = true; 

$(element).on('DOMMouseScroll mousewheel wheel', function(event) { 
    // Timeout active? do nothing 
    if (timeout !== null) { 
     event.preventDefault(); 
     return false; 
    } 

    // Get scroll delta, check for the different kind of event indexes regarding delta/scrolls 
    var delta = event.originalEvent.detail ? event.originalEvent.detail * (-120) : (
      event.originalEvent.wheelDelta ? event.originalEvent.wheelDelta : (
        event.originalEvent.deltaY ? (event.originalEvent.deltaY * 1) * (-120) : 0 
    )); 

    // Get direction 
    var scrollDown = delta < 0; 

    // This is where you do something with scrolling and reset the timeout 
    // If the container can be scrolling, be sure to prevent the default mouse action 
    // otherwise the parent container can scroll too 
    if (canScroll) { 
     timeout = setTimeout(function(){timeout = null;}, speed); 
     event.preventDefault(); 
     return false; 
    } 

    // Container couldn't scroll, so let the parent scroll 
    return true; 
}); 

È possibile applicare questo a qualsiasi elemento scorrevole e nel mio caso, ho usato gli strumenti jQuery libreria scorrevole ma finito pesantemente personalizzandolo in modo da migliorare il supporto del browser così come l'aggiunta di funzionalità personalizzate specifiche per il mio caso d'uso.

Una cosa su cui prestare attenzione è garantire che il timeout sia sufficientemente lungo da impedire l'attivazione di più eventi senza interruzioni. La mia soluzione è efficace solo se si desidera controllare la velocità di scorrimento degli elementi e quanti devono essere fatti scorrere contemporaneamente. Se si aggiunge console.log(event) all'inizio della funzione listener e si scorre utilizzando una periferica di scorrimento continua, si verificheranno molti eventi di rotellina del mouse attivati.

Fastidiosamente Firefox scorrere DOMMouseScroll non si innesca sul Magic Mouse o dispositivi di scorrimento continuo, ma per i dispositivi di scorrimento normali che hanno un rotolo e arresto attraverso il ciclo di clic della rotellina del mouse.

Problemi correlati