Запрет scrollTop от вызова события прокрутки
Я пытаюсь создать такое поведение: когда пользователь прокручивает колесо мыши (или нажимает ↓), веб-страница прокручивается вниз по высоте окна.
Я получил следующий код:
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;
}
});
Но это работает не так, как я ожидаю: на странице события прокрутки прокручивается до самого края (внизу или вверху). Что мне не хватает?
2 ответа
Нет простого способа переопределить функцию прокрутки браузера по умолчанию. Вот один из способов сделать то, что вы хотите, но для управления колесом прокрутки мыши требуется плагин jquery- mousewheel Брэндона Аарона:
$(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);
});
});
Вот скрипка для демонстрации кода. Все это работает очень хорошо, за исключением одного неприятного недостатка моего решения. $('html').css('overflow', 'hidden');
удаляет полосу прокрутки браузера.
Проблема в том, что вы используете scrollTop()
которые запускают событие прокрутки внутри самого события прокрутки окна.
Таким образом, в основном, с кодом, который вы написали, вы запускаете бесконечный цикл, потому что как только первое событие прокрутки запускается, другое запускается scrollTop()
в то время как ваш preventScroll
переменная все еще не установлена в ложь и так далее.
Чтобы ваш код работал, вам нужно установить preventScroll
переменная к false
внутри функции setTimeout вот так:
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);
}
});
Мы добавляем некоторую "задержку", прежде чем мы установим preventScroll
в false
, Таким образом, когда вы звоните scrollTop()
preventScroll
переменная по-прежнему будет иметь значение true!
Вот рабочая скрипка: http://jsfiddle.net/J6Fcm/ (я немного изменил ваш код, чтобы позволить шагам прокрутки работать как положено)