jQuery scroll () определяет, когда пользователь прекращает прокрутку
ок с этим..
$(window).scroll(function()
{
$('.slides_layover').removeClass('showing_layover');
$('#slides_effect').show();
});
Я могу сказать, когда кто-то прокручивает насколько я понимаю. Так что с этим я пытаюсь выяснить, как поймать, когда кто-то остановился. Из приведенного выше примера вы можете видеть, что я удаляю класс из набора элементов во время прокрутки. Однако я хочу вернуть этот класс, когда пользователь прекратит прокрутку.
причина этого в том, что я намерен иметь layover 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 РЕПО для обновления!
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
-обработчик событий, за исключением того, что вы можете передать дополнительный параметр в качестве последнего:$(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 / debounce
jQuery debounce это хороший вариант для таких проблем, как эта. jsFidlle
$(window).scroll($.debounce( 250, true, function(){ $('#scrollMsg').html('SCROLLING!'); })); $(window).scroll($.debounce( 250, function(){ $('#scrollMsg').html('DONE!'); }));
второй параметр-это флаг "at_begin". Здесь я показал, как выполнить код как в "scroll start", так и в "scroll finish".
Используя Лодашь
как предложил Барри П,jsFiddle,подчеркивание или лодашь также есть debounce, каждый с немного другие API.
$(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) ); } }; })();
я согласился с некоторыми комментариями выше, что прослушивание тайм-аута было недостаточно точным, поскольку это будет срабатывать, когда вы перестанете перемещать полосу прокрутки достаточно долго, а не когда вы прекратите прокрутку. Я думаю, что лучшее решение-слушать, как пользователь отпускает мышь (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);
очень маленькая версия с возможностью начала и конца
ок это то, что я использовал раньше. В основном вы смотрите удержание ссылки до последнего
scrollTop()
. Как только ваш тайм-аут очищается, вы проверяете текущийscrollTop()
и если они одинаковы,вы сделали прокрутку.$(window).scroll((e) -> clearTimeout(scrollTimer) $('header').addClass('hidden') scrollTimer = setTimeout((() -> if $(this).scrollTop() is currentScrollTop $('header').removeClass('hidden') ), animationDuration) currentScrollTop = $(this).scrollTop() )
пожалуйста, проверьте jQuery mobile scrollstop event
$(document).on("scrollstop",function(){ alert("Stopped scrolling!"); });