用户停止滚动时的事件
Posted
技术标签:
【中文标题】用户停止滚动时的事件【英文标题】:Event when user stops scrolling 【发布时间】:2011-04-11 16:58:14 【问题描述】:当用户滚动页面时,我想做一些花哨的 jQuery 东西。但是我不知道如何解决这个问题,因为只有scroll()
方法。
有什么想法吗?
【问题讨论】:
【参考方案1】:您可以使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>
【讨论】:
1000 毫秒比 250 毫秒要好很多 这种技术也称为事件去抖动。 它甚至可以在 100 毫秒内运行良好? 不要使用 10 毫秒,否则滚动会卡住。顺便说一句,您也可以在 DIV 上绑定 scrollEnd 扩展。在这里帮助了我:***.com/q/71239600/1066234【参考方案2】:这是一个使用 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
);
我用它来滚动和调整大小。
【讨论】:
这被称为“去抖动”方法。更多信息(和可重复使用的功能)在这里:davidwalsh.name/function-debounce【参考方案3】:以下是基于上述相同想法的另一个更通用的解决方案:
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);
【讨论】:
另外,您可以通过将值 500 更改为较低的值 (~~100) 来控制触发此事件的速度【参考方案4】:我也需要实现讨论过的 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
//
);
希望这会帮助/激励某人
【讨论】:
【参考方案5】:为什么这么复杂?正如文档指出的那样,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
测试的一些发现:
http://jsfiddle.net/TRNCFRMCN/1Lygop32/4/.
【讨论】:
实际上,这很好用。不幸的是,在演示中使用滚动条不起作用,尽管我相信这只是因为fadeIn
函数。将不得不进行更多测试以找出是否还有更多错误,但做得好,效果很好!对于这么小的任务,其他解决方案要复杂得多。
谢谢。对未发表评论的投票者:“现在好点了吗?” %)P
现在,如果我只想保持向上滚动事件的条件,那么如何检测向上滚动?你能帮忙吗?【参考方案6】:
没有“scrollEnd”这样的事件。我建议您使用setInterval
每隔一段时间(例如,200 毫秒)检查一次scroll()
返回的值,并记录当前值和先前值之间的增量。如果 delta 变为零,您可以将其用作您的事件。
【讨论】:
除非您保留对处理程序的引用并在 delta 变为零时调用clearInterval
,或者干脆改用 setTimeout
。
偶然否决这个答案,现在是locked...抱歉【参考方案7】:
滚动启动和滚动停止功能是 jquery mobile 的一部分。
使用滚动停止的示例:
$(document).on("scrollstop",function()
alert("Stopped scrolling!");
);
希望这对某人有所帮助。
【讨论】:
这对我来说似乎并不火 :( @RatherNotsay 它不适合你?我在生产中有这个,它似乎工作得很好。您是否包含了 jquery 的移动版本?和jquery不一样。 我肯定有 JQuery Mobile,但它可能是缺少该组件的自定义构建?我现在已经继续前进,但如果我重新访问,我会更新。【参考方案8】:我从我拼凑在一起的一个快速片段中提取了一些代码,作为示例(请注意,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;
【讨论】:
以上是关于用户停止滚动时的事件的主要内容,如果未能解决你的问题,请参考以下文章