滚动事件发射次数太多。 我只想让它每秒钟发射一次

我有一个“无限滚动”的页面。 它计算页面结尾和当前页面之间的差异,如果差异足够小,则加载更多内容。 代码是这样的使用jQuery这样的东西:

$(window).on('scroll', function() { if (window.pageYOffset > loadMoreButton.offsetTop - 1000) # load more content via ajax } 

现在,问题是每次滚动,这个事件每滚动多次触发。 我想每x毫秒就会发生一次火灾。 我将如何做到这一点?

检查Underscore.js库的“节stream”方法。

http://underscorejs.org/#throttle

它给出的例子正是你所要求的 – 限制你必须经常处理滚动事件。

解决这个问题的一种方法是定义一个时间间隔,并且只在该时间间隔内处理一次滚动事件。 如果在该时间间隔内出现多个滚动事件,则忽略该事件并仅在该时间间隔过去时才处理它。

 var scrollTimer, lastScrollFireTime = 0; $(window).on('scroll', function() { var minScrollTime = 100; var now = new Date().getTime(); function processScroll() { console.log(new Date().getTime().toString()); } if (!scrollTimer) { if (now - lastScrollFireTime > (3 * minScrollTime)) { processScroll(); // fire immediately on first scroll lastScrollFireTime = now; } scrollTimer = setTimeout(function() { scrollTimer = null; lastScrollFireTime = new Date().getTime(); processScroll(); }, minScrollTime); } }); 

这将立即触发第一个滚动事件,然后在滚动条被移动的同时大约每隔100ms获得一次滚动事件,然后在滚动条停止移动后最后一个事件。 您可以通过将参数更改为setTimeout (当前设置为100)来调整事件的频率。

这里有一个演示: http : //jsfiddle.net/jfriend00/EBEqZ/你需要打开debugging控制台窗口,开始移动内容窗口中的滚动条,然后在debugging控制台窗口中观察每个滚动事件的时间。 在我的Chrome版本中,它们被设置为100ms的最小间隔,并且似乎每100-200ms发生一次。

jQuery的创build者John Resig有一个很好的解释来解决这个问题。

 var outerPane = $details.find(".details-pane-outer"), didScroll = false; $(window).scroll(function() { didScroll = true; }); setInterval(function() { if ( didScroll ) { didScroll = false; // Check your page position and then // Load in more results } }, 250); 

来源: http : //ejohn.org/blog/learning-from-twitter/

 var isWorking = 0; $(window).on('scroll', function() { if(isWorking==0) { isWorking=1; if (window.pageYOffset > loadMoreButton.offsetTop - 1000) # load more content via ajax setTimeout(function(){isWorking=0},1000); } } 
 var now = new Date().getTime(); $(window).scroll( function () { if (window.pageYOffset > loadMoreButton.offsetTop - 1000) { if (new Date().getTime() - now > 1000) { console.log("Task executed once per second"); now = new Date().getTime(); } } }); 

要么

您可以使用节streamfunction调用: 调节function调用

 function throttle(fn, threshhold, scope) { threshhold || (threshhold = 250); var last, deferTimer; return function () { var context = scope || this; var now = +new Date, args = arguments; if (last && now < last + threshhold) { // hold on to it clearTimeout(deferTimer); deferTimer = setTimeout(function () { last = now; fn.apply(context, args); }, threshhold); } else { last = now; fn.apply(context, args); } }; } 

你可以这样调用它:

 $('body').on('mousemove', throttle(function (event) { console.log('tick'); }, 1000)); 

这是一个解决scheme,不需要使用额外的JS库或插件,旨在简化。 它可能不像其他实现那样高效,但是每当你滚动时它绝对是开启主要事件的一个步骤。

这是从Danny Van Kooten的博客文章中提取出来的。 在我的博客上,我用它来延迟我的onscroll()事件,用于我的back-to-topbutton。

 var timer; $(window).scroll(function() { if(timer) { window.clearTimeout(timer); } timer = window.setTimeout(function() { // actual code here. Your call back function. console.log( "Firing!" ); }, 100); }); 

您还可以通过将variables移出callback函数来进一步提高性能,以避免不必要的重新计算,例如$(window).height()或一些静态div元素的高度,一旦页面加载。

这里有一个例子是根据我的用例改编的。

 var scrollHeight = $("#main-element").height(); //never changes, no need to recalculate. $(window).on('scroll', function() { if (timer) window.clearTimeout(timer); timer = window.setTimeout(function() { var scrollPosition = $(window).height() + $(window).scrollTop(); if ($(window).scrollTop() < 500) $(".toggle").fadeIn(800); else $(".toggle").fadeOut(800); }, 150); //only fire every 150 ms. }); 

这将实际function限制为每150ms执行一次,否则,如果150ms未通过,则将计时器重置为0。 调整值,以适应你的需要。

多次滚动的滚动是正确的,你应该能够每次都有不同的滚动位置。 我想你需要设置一个计时器,当你第一次进入滚动事件,像你提到的X毫秒,并logging时间戳,然后下一次滚动事件触发,检查最后一个触发时间,并忽略它,如果它在x毫秒,并在你的Timer动作中做真正的工作。