jQuery scroll() определяет, когда пользователь прекращает прокрутку
Хорошо с этим..
$(window).scroll(function()
{
$('.slides_layover').removeClass('showing_layover');
$('#slides_effect').show();
});
Я могу сказать, когда кто-то прокручивает от того, что я понимаю. Итак, с этим я пытаюсь понять, как ловить, когда кто-то остановился. Из приведенного выше примера видно, что я удаляю класс из набора элементов во время прокрутки. Однако я хочу снова включить этот класс, когда пользователь прекращает прокрутку.
Причиной этого является то, что я намерен устроить промежуточное шоу во время прокрутки страницы, чтобы придать странице особый эффект, над которым я пытаюсь работать. Но один класс, который я пытаюсь удалить, прокручивая, конфликтует с этим эффектом, так как это эффект прозрачности для некоторой природы.
10 ответов
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do something
console.log("Haven't scrolled in 250ms!");
}, 250));
});
Обновить
Я написал расширение для улучшения JQuery по умолчанию on
-обработчик события. Он присоединяет функцию-обработчик события для одного или нескольких событий к выбранным элементам и вызывает функцию-обработчик, если событие не было запущено в течение заданного интервала. Это полезно, если вы хотите вызвать обратный вызов только после задержки, например, события изменения размера или чего-то подобного.
Важно проверить наличие обновлений в github-repo!
https://github.com/yckart/jquery.unevent.js
;(function ($) {
var on = $.fn.on, timer;
$.fn.on = function () {
var args = Array.apply(null, arguments);
var last = args[args.length - 1];
if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);
var delay = args.pop();
var fn = args.pop();
args.push(function () {
var self = this, params = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(self, params);
}, delay);
});
return on.apply(this, args);
};
}(this.jQuery || this.Zepto));
Используйте это как любой другой on
или же bind
-event обработчик, за исключением того, что вы можете передать дополнительный параметр как последний:
$(window).on('scroll', function(e) {
console.log(e.type + '-event was 250ms not triggered');
}, 250);
http://yckart.github.com/jquery.unevent.js/
(эта демонстрация использует resize
вместо scroll
, но кого это волнует?!)
Использование jQuery throttle / debounce
jQuery debounce хорош для таких проблем. jsFidlle
$(window).scroll($.debounce( 250, true, function(){
$('#scrollMsg').html('SCROLLING!');
}));
$(window).scroll($.debounce( 250, function(){
$('#scrollMsg').html('DONE!');
}));
Второй параметр - это флаг at_begin. Здесь я показал, как выполнять код как при "начале прокрутки", так и при "конце прокрутки".
Использование Lodash
Как предположил Барри П, jsFiddle, http://underscorejs.org/ или lodash также имеют отскок, каждый с немного отличающимся apis.
$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('SCROLLING!');
}, 150, { 'leading': true, 'trailing': false }));
$(window).scroll(_.debounce(function(){
$('#scrollMsg').html('STOPPED!');
}, 150));
Роб W предложил, я проверю еще один пост здесь в стеке, который по сути был похож на мой оригинальный пост. Прочитав который я нашел ссылку на сайт:
http://james.padolsey.com/javascript/special-scroll-events-for-jquery/
Это на самом деле помогло решить мою проблему очень хорошо после небольшой настройки для моих собственных нужд, но в целом помогло избавиться от большого количества болтовни и сэкономило мне около 4 часов, чтобы разобраться с этим самостоятельно.
Видя, что у этого поста есть некоторые достоинства, я решил, что вернусь и предоставлю код, найденный первоначально по упомянутой ссылке, на тот случай, если автор когда-нибудь решит пойти в другом направлении с сайтом и в итоге уберет ссылку.
(function(){
var special = jQuery.event.special,
uid1 = 'D' + (+new Date()),
uid2 = 'D' + (+new Date() + 1);
special.scrollstart = {
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
} else {
evt.type = 'scrollstart';
jQuery.event.handle.apply(_self, _args);
}
timer = setTimeout( function(){
timer = null;
}, special.scrollstop.latency);
};
jQuery(this).bind('scroll', handler).data(uid1, handler);
},
teardown: function(){
jQuery(this).unbind( 'scroll', jQuery(this).data(uid1) );
}
};
special.scrollstop = {
latency: 300,
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout( function(){
timer = null;
evt.type = 'scrollstop';
jQuery.event.handle.apply(_self, _args);
}, special.scrollstop.latency);
};
jQuery(this).bind('scroll', handler).data(uid2, handler);
},
teardown: function() {
jQuery(this).unbind( 'scroll', jQuery(this).data(uid2) );
}
};
})();
Стиль ES6 с проверкой начала прокрутки.
function onScrollHandler(params: {
onStart: () => void,
onStop: () => void,
timeout: number
}) {
const {onStart, onStop, timeout = 200} = params
let timer = null
return (event) => {
if (timer) {
clearTimeout(timer)
} else {
onStart && onStart(event)
}
timer = setTimeout(() => {
timer = null
onStop && onStop(event)
}, timeout)
}
}
Применение:
yourScrollableElement.addEventListener('scroll', onScrollHandler({
onStart: (event) => {
console.log('Scrolling has started')
},
onStop: (event) => {
console.log('Scrolling has stopped')
},
timeout: 123 // Remove to use default value
}))
Я согласился с некоторыми комментариями выше, что прослушивание тайм-аута не было достаточно точным, так как это сработает, когда вы перестанете перемещать полосу прокрутки достаточно долго, а не когда перестанете прокручивать. Я думаю, что лучшее решение состоит в том, чтобы прислушиваться к тому, как пользователь отпускает мышь (mouseup), как только он начинает прокручивать:
$(window).scroll(function(){
$('#scrollMsg').html('SCROLLING!');
var stopListener = $(window).mouseup(function(){ // listen to mouse up
$('#scrollMsg').html('STOPPED SCROLLING!');
stopListner(); // Stop listening to mouse up after heard for the first time
});
});
и пример его работы можно увидеть в этом JSFiddle
Вы можете установить интервал, который выполняется каждые 500 мс или около того, в соответствии с приведенным ниже текстом:
var curOffset, oldOffset;
oldOffset = $(window).scrollTop();
var $el = $('.slides_layover'); // cache jquery ref
setInterval(function() {
curOffset = $(window).scrollTop();
if(curOffset != oldOffset) {
// they're scrolling, remove your class here if it exists
if($el.hasClass('showing_layover')) $el.removeClass('showing_layover');
} else {
// they've stopped, add the class if it doesn't exist
if(!$el.hasClass('showing_layover')) $el.addClass('showing_layover');
}
oldOffset = curOffset;
}, 500);
Я не проверял этот код, но принцип должен работать.
function scrolled() {
//do by scroll start
$(this).off('scroll')[0].setTimeout(function(){
//do by scroll end
$(this).on('scroll',scrolled);
}, 500)
}
$(window).on('scroll',scrolled);
очень маленькая версия с возможностью начала и окончания
Это обнаруживает остановку прокрутки через 1 миллисекунду (или изменяет ее), используя глобальный таймер:
var scrollTimer;
$(window).on("scroll",function(){
clearTimeout(scrollTimer);
//Do what you want whilst scrolling
scrollTimer=setTimeout(function(){afterScroll()},1);
})
function afterScroll(){
//I catched scroll stop.
}
Хорошо, это то, что я использовал раньше. В основном вы смотрите удерживать реф до последнего scrollTop()
, После истечения времени ожидания вы проверяете текущий scrollTop()
и если они одинаковы, вы закончили прокрутку.
$(window).scroll((e) ->
clearTimeout(scrollTimer)
$('header').addClass('hidden')
scrollTimer = setTimeout((() ->
if $(this).scrollTop() is currentScrollTop
$('header').removeClass('hidden')
), animationDuration)
currentScrollTop = $(this).scrollTop()
)
Для тех, кому все еще нужно это вот решение
$(function(){
var t;
document.addEventListener('scroll',function(e){
clearTimeout(t);
checkScroll();
});
function checkScroll(){
t = setTimeout(function(){
alert('Done Scrolling');
},500); /* You can increase or reduse timer */
}
});
Пожалуйста, проверьте событие jquery mobile scrollstop
$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});
Вот как вы можете справиться с этим:
var scrollStop = function (callback) {
if (!callback || typeof callback !== 'function') return;
var isScrolling;
window.addEventListener('scroll', function (event) {
window.clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
callback();
}, 66);
}, false);
};
scrollStop(function () {
console.log('Scrolling has stopped.');
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
</body>
</html>
Это должно работать:
var Timer;
$('.Scroll_Table_Div').on("scroll",function()
{
// do somethings
clearTimeout(Timer);
Timer = setTimeout(function()
{
console.log('scrolling is stop');
},50);
});