2012-10-06 11 views
5

Sto tentando di creare questo comportamento: quando l'utente fa scorrere una rotellina del mouse (o preme ), la pagina Web scorre verso il basso all'altezza della finestra.Evita scrollTop dalla chiamata all'evento di scorrimento

ho finito con seguente codice:

var newScrollTop, 
    oldScrollTop = $(window).scrollTop(), 
    preventScroll = false; 
$(window).scroll(function() { 
    if (!preventScroll) { 
     preventScroll = true; 
     newScrollTop = $(this).scrollTop(); 
     if (newScrollTop > oldScrollTop) { 
      $(this).scrollTop(oldScrollTop + $(window).height()); 
     } 
     else { 
      $(this).scrollTop(oldScrollTop - $(window).height()); 
     } 
     oldScrollTop = newScrollTop; 
     preventScroll = false; 
    } 
}); 

Ma questo non funziona come mi aspetto che: a pagina evento di scorrimento è scorrere fino al limite (inferiore o superiore). Cosa mi manca?

risposta

2

Non esiste un modo semplice per ignorare la funzionalità di scorrimento del browser predefinita. Ecco un modo di fare ciò che si vuole, ma richiede di jquery-mousewheel plugin Brandon Aaron per gestire la rotella del mouse:

$(function() { 
    // Ugly hack to disable browser scrolling (downside: hides scrollbar!!!) 
    $('html').css('overflow', 'hidden'); 

    // Get viewport height by which to scroll (up or down) 
    var viewportHeight = $(window).height(); 

    // Recache viewport height on browser resize 
    $(window).on('resize', function() { 
     viewportHeight = $(window).height(); 
    }); 

    // Scroll on mousewheel 
    $('html').on('mousewheel', function(event, delta, deltaX, deltaY) { 
     // scroll down 
     if (deltaY < 0) 
      window.scrollBy(0, viewportHeight); 
     // scroll up 
     else 
      window.scrollBy(0, -viewportHeight); 
    }); 

    // Disable document keypress event 
    // which would scroll the content even with "overlow: hidden" 
    $(document).on('keypress', function(){ 
     return false; 
    }); 

    // Scroll on arrow up/down keys 
    $(document).on('keydown', function(event){ 
     // arrow down key 
     if (event.which == 40) 
      window.scrollBy(0, viewportHeight); 
     // arrow up key 
     if (event.which == 38) 
      window.scrollBy(0, -viewportHeight); 
    }); 
}); 

Ecco un fiddle di demo del codice. Funziona tutto molto bene, tranne che c'è un brutto inconveniente alla mia soluzione. Lo $('html').css('overflow', 'hidden'); rimuove la barra di scorrimento del browser.

+0

Ho già barre di scorrimento nascoste e invalidante 'keypress' sembra essere inutile. L'altra parte funziona come un fascino. Grazie molto. – Pavlo

+1

Felice di poter essere di aiuto. Ho notato un piccolo bug con la mia soluzione, più esattamente se ridimensionate il browser viewportHeight non è più valido dato che è stato memorizzato nella cache di DOMReady. Ho aggiornato il codice per gestirlo. – Bogdan

+0

Grazie. Il tuo voto mi ha superato quel punto :-). – Bogdan

4

Il problema è che si sta utilizzando scrollTop() che attiva un evento di scorrimento all'interno dell'evento di scorrimento della finestra.

Quindi, in pratica, con il codice che hai scritto si esegue in un ciclo infinito perché non appena il primo evento di scorrimento viene attivato un altro è innescato da scrollTop() mentre la variabile preventScroll non è ancora impostata su false e così via.

Per rendere il vostro lavoro di codice si dovrebbe impostare la variabile preventScroll-false all'interno della funzione setTimeout in questo modo:

var newScrollTop, 
    oldScrollTop = $(window).scrollTop(), 
    preventScroll = false; 

$(window).scroll(function() { 
    if (!preventScroll) { 
     preventScroll = true; 
     newScrollTop = $(this).scrollTop(); 
     if (newScrollTop > oldScrollTop) { 
      $(this).scrollTop(oldScrollTop + $(window).height()); 
     } 
     else { 
      $(this).scrollTop(oldScrollTop - $(window).height()); 
     } 
     oldScrollTop = newScrollTop; 

     setTimeout(function(){ preventScroll = false; }, 0); 
    } 
}); 

Aggiungiamo un po 'di "ritardo" prima abbiamo impostato preventScroll-false. In questo modo quando si chiama la variabile scrollTop()preventScroll sarà impostata su true!

Ecco un violino di lavoro: http://jsfiddle.net/J6Fcm/ (ho modificato un po 'il codice per permettere le operazioni di scorrimento funzionano come previsto)

Problemi correlati