Я хочу сделать некоторые причудливые вещи jQuery, когда пользователь прокручивает страницу. Но я не знаю, как решить эту проблему, поскольку существует только метод scroll().
Любые идеи?
Я хочу сделать некоторые причудливые вещи jQuery, когда пользователь прокручивает страницу. Но я не знаю, как решить эту проблему, поскольку существует только метод scroll().
Любые идеи?
Вы можете сделать scroll()
тайм-аут, который будет перезаписываться каждый раз, когда пользователь прокручивает. Таким образом, когда он останавливается через определенное количество миллисекунд, ваш script запускается, но если он прокручивается, тем временем счетчик снова запустится, а script будет ждать, пока он будет снова прокручиваться.
Update:
Поскольку этот вопрос снова получил какое-то действие, я решил, что могу обновить его с помощью расширения jQuery, которое добавит scrollEnd
event
// extension:
$.fn.scrollEnd = function(callback, timeout) {
$(this).scroll(function(){
var $this = $(this);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,timeout));
});
};
// how to call it (with a 1000ms timeout):
$(window).scrollEnd(function(){
alert('stopped scrolling');
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height: 200vh">
Long div
</div>
Вот простой пример использования setTimeout для запуска функции, когда пользователь перестает прокручивать:
(function() {
var timer;
$(window).bind('scroll',function () {
clearTimeout(timer);
timer = setTimeout( refresh , 150 );
});
var refresh = function () {
// do stuff
console.log('Stopped Scrolling');
};
})();
Таймер очищается при запуске события прокрутки. После прокрутки останавливается функция обновления.
Или как плагин:
$.fn.afterwards = function (event, callback, timeout) {
var self = $(this), delay = timeout || 16;
self.each(function () {
var $t = $(this);
$t.on(event, function(){
if ($t.data(event+'-timeout')) {
clearTimeout($t.data(event+'-timeout'));
}
$t.data(event + '-timeout', setTimeout(function () { callback.apply($t); },delay));
})
});
return this;
};
Чтобы запустить обратный вызов после 100 мс последнего события прокрутки в div (с пространством имен):
$('div.mydiv').afterwards('scroll.mynamespace', function(e) {
// do stuff when stops scrolling
$(this).addClass('stopped');
}, 100
);
Я использую это для прокрутки и изменения размера.
Вот еще одно общее решение, основанное на тех же идеях:
var delayedExec = function(after, fn) {
var timer;
return function() {
timer && clearTimeout(timer);
timer = setTimeout(fn, after);
};
};
var scrollStopper = delayedExec(500, function() {
console.log('stopped it');
});
document.getElementById('box').addEventListener('scroll', scrollStopper);
Почему так сложно? Как указывает документация, это http://jsfiddle.net/x3s7F/9/ работает!
$('.frame').scroll(function() {
$('.back').hide().fadeIn(100);
}
http://api.jquery.com/scroll/.
Примечание. Событие scroll
в Windows Chrome по-разному относится ко всем остальным. Вам нужно быстро прокрутить, чтобы получить то же самое, что и результат. FF. Посмотрите https://liebdich.biz/back.min.js функцию "X".
Некоторые результаты моего теста how many ms a scroll event
:
Нет такого события, как "scrollEnd". Я рекомендую вам проверять значение, возвращаемое scroll()
каждый раз через некоторое время (скажем, 200 мс) с помощью setInterval
, и записывать дельта между текущим и предыдущим значениями. Если дельта становится нулевым, вы можете использовать ее как свое событие.
Существуют функции scrollstart и scrollstop, которые являются частью jQuery mobile.
Пример использования scrollstop:
$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});
Надеюсь, это поможет кому-то.
Мне нужно было также реализовать обсуждаемое событие onScrollEnd. Идея использования таймера работает для меня.
Я реализую это с помощью шаблона модуля JavaScript:
var WindowCustomEventsModule = (function(){
var _scrollEndTimeout = 30;
var _delayedExec = function(callback){
var timer;
return function(){
timer && clearTimeout(timer);
timer = setTimeout(callback, _scrollEndTimeout);
}
};
var onScrollEnd = function(callback) {
window.addEventListener('scroll', _delayedExec(callback), false);
};
return {
onScrollEnd: onScrollEnd
}
})();
// usage example
WindowCustomEventsModule.onScrollEnd(function(){
//
// do stuff
//
});
Надеюсь, что это поможет/вдохновит кого-то.
Я вытащил некоторый код из быстрой части, которую я объединил, что делает это в качестве примера (обратите внимание, что scroll.chain - это объект, содержащий два начальных и конечных массива, которые являются контейнерами для функций обратного вызова). Также обратите внимание, что я использую jQuery и подчеркивание здесь.
$('body').on('scroll', scrollCall);
scrollBind('end', callbackFunction);
scrollBind('start', callbackFunction);
var scrollCall = function(e) {
if (scroll.last === false || (Date.now() - scroll.last) <= 500) {
scroll.last = Date.now();
if (scroll.timeout !== false) {
window.clearTimeout(scroll.timeout);
} else {
_(scroll.chain.start).each(function(f){
f.call(window, {type: 'start'}, e.event);
});
}
scroll.timeout = window.setTimeout(self.scrollCall, 550, {callback: true, event: e});
return;
}
if (e.callback !== undefined) {
_(scroll.chain.end).each(function(f){
f.call(window, {type: 'end'}, e.event);
});
scroll.last = false;
scroll.timeout = false;
}
};
var scrollBind = function(type, func) {
type = type.toLowerCase();
if (_(scroll.chain).has(type)) {
if (_(scroll.chain[type]).indexOf(func) === -1) {
scroll.chain[type].push(func);
return true;
}
return false;
}
return false;
}