【发布时间】:2011-04-11 16:58:14
【问题描述】:
当用户滚动页面时,我想做一些花哨的 jQuery 东西。但是我不知道如何解决这个问题,因为只有scroll() 方法。
有什么想法吗?
【问题讨论】:
标签: javascript jquery scroll jquery-events
当用户滚动页面时,我想做一些花哨的 jQuery 东西。但是我不知道如何解决这个问题,因为只有scroll() 方法。
有什么想法吗?
【问题讨论】:
标签: javascript jquery scroll jquery-events
您可以使scroll() 有一个超时,每次用户滚动时都会被覆盖。这样,当他在一定的毫秒数后停止时,您的脚本就会运行,但如果他同时滚动,计数器将重新开始,脚本将等到他再次滚动完成。
更新:
因为这个问题又得到了一些行动,我想我不妨用一个添加 scrollEnd 事件的 jQuery 扩展来更新它
// extension:
$.fn.scrollEnd = function(callback, timeout) {
$(this).on('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://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></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;
};
在 div 上的最后一个滚动事件 100 毫秒后触发回调(带有命名空间):
$('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);
【讨论】:
我也需要实现讨论过的 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
//
});
希望这会帮助/激励某人
【讨论】:
为什么这么复杂?正如文档指出的那样,http://jsfiddle.net/x3s7F/9/ 有效!
$('.frame').scroll(function() {
$('.back').hide().fadeIn(100);
}
http://api.jquery.com/scroll/.
注意:Windows Chrome 上的scroll 事件与所有其他事件不同。您需要快速滚动才能获得与例如结果相同的结果。法郎。看https://liebdich.biz/back.min.js的“X”函数。
我的how many ms a scroll event 测试的一些发现:
【讨论】:
fadeIn 函数。将不得不进行更多测试以找出是否还有更多错误,但做得好,效果很好!对于这么小的任务,其他解决方案要复杂得多。
没有“scrollEnd”这样的事件。我建议您使用setInterval 每隔一段时间(例如,200 毫秒)检查一次scroll() 返回的值,并记录当前值和先前值之间的增量。如果 delta 变为零,您可以将其用作您的事件。
【讨论】:
clearInterval,或者干脆改用 setTimeout。
滚动启动和滚动停止功能是 jquery mobile 的一部分。
使用滚动停止的示例:
$(document).on("scrollstop",function(){
alert("Stopped scrolling!");
});
希望这对某人有所帮助。
【讨论】:
我从我拼凑在一起的一个快速片段中提取了一些代码,作为示例(请注意,scroll.chain 是一个包含两个数组 start 和 end 的对象,它们是回调函数的容器)。另请注意,我在这里使用的是 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;
}
【讨论】: