在屏幕上添加位置监听器

我想在我的网站上设置一些东西,当你在页面底部的15%内滚动时,一个元素从侧面跳出来…我不知道如何开始这里…我应该添加一个听众的滚动function还是什么?

我正在尝试重新创建此页面底部的效果: http : //www.nytimes.com/2011/01/25/world/europe/25moscow.html? _ r = 1

更新

我有这个代码….

console.log(document.body.scrollTop); //shows 0 console.log(document.body.scrollHeight * 0.85); //shows 1038.7 if (document.body.scrollTop > document.body.scrollHeight * 0.85) { console.log(); $('#flyout').animate({ right: '0' }, 5000, function() { }); } 

当我滚动到页面底部时, console.log()值没有改变。 该页面是我的视口的两倍。

[ 工作演示 ]

 $(document).ready(function () { var ROOT = (function () { var html = document.documentElement; var htmlScrollTop = html.scrollTop++; var root = html.scrollTop == htmlScrollTop + 1 ? html : document.body; html.scrollTop = htmlScrollTop; return root; })(); // may be recalculated on resize var limit = (document.body.scrollHeight - $(window).height()) * 0.85; var visible = false; var last = +new Date; $(window).scroll(function () { if (+new Date - last > 30) { // more than 30 ms elapsed if (visible && ROOT.scrollTop < limit) { setTimeout(function () { hide(); visible = false; }, 1); } else if (!visible && ROOT.scrollTop > limit) { setTimeout(function () { show(); visible = true; }, 1); } last = +new Date; } }); }); 

我知道这是一个老话题,但上面收到复选标记的代码也触发了$(window).scroll()事件监听器太多次了。

我猜twitter在某个方面也有同样的问题。 John Resig在这里写了博客: http : //ejohn.org/blog/learning-from-twitter/

 $(document).ready(function(){ var ROOT = (function () { var html = document.documentElement; var htmlScrollTop = html.scrollTop++; var root = html.scrollTop == htmlScrollTop + 1 ? html : document.body; html.scrollTop = htmlScrollTop; return root; })(); // may be recalculated on resize var limit = (document.body.scrollHeight - $(window).height()) * 0.85; var visible = false; var last = +new Date; var didScroll = false; $(window).scroll(function(){ didScroll = true; }) setInterval(function(){ if(didScroll){ didScroll = false; if (visible && ROOT.scrollTop < limit) { hideCredit(); visible = false; } else if (!visible && ROOT.scrollTop > limit) { showCredit(); visible = true; } } }, 30); function hideCredit(){ console.log('The hideCredit function has been called.'); } function showCredit(){ console.log('The showCredit function has been called.'); } }); 

因此,两个代码块之间的区别在于调用定时器的时间和方式。 在这段代码中,计时器被关闭。 因此,每隔30分钟,它会检查页面是否已滚动。 如果它已被滚动,那么它会检查我们是否已经通过了我们想要显示隐藏内容的页面上的点。 然后,如果检查为true,则调用实际函数以显示内容。 (就我而言,我刚刚在那里打印出一个console.log。

这似乎比其他解决方案更好,因为最终函数每次迭代只调用一次。 使用另一种解决方案,最终的function被调用4到5次。 这必须节省资源。 但也许我错过了一些东西。

像这样的东西应该工作:

 $(window).scroll(function() { if (document.body.scrollTop > document.body.scrollHeight * 0.85) { // flyout } }); 

document.body.scrollTop在所有浏览器上可能无法正常工作(它实际上取决于浏览器和doctype); 所以我们需要在函数中抽象出来。

此外,我们只需要飞行一次。 所以我们可以在飞出后取消绑定事件处理程序。

并且我们不希望弹出效果减慢滚动速度,因此我们将从事件循环中运行我们的flytout函数(通过使用setTimeout())。

这是最终的代码:

 // we bind the scroll event, with the 'flyout' namespace // so we can unbind easily $(window).bind('scroll.flyout', (function() { // this function is defined only once // it is private to our event handler function getScrollTop() { // if one of these values evaluates to false, this picks the other return (document.documentElement.scrollTop||document.body.scrollTop); } // this is the actual event handler // it has the getScrollTop() in its scope return function() { if (getScrollTop() > (document.body.scrollHeight-$(window).height()) * 0.85) { // flyout // out of the event loop setTimeout(function() { alert('flyout!'); }, 1); // unbind the event handler // so that it's not call anymore $(this).unbind('scroll.flyout'); } }; })()); 

所以最后,只有getScrollTop() > document.body.scrollHeight * 0.85在每个滚动事件中执行,这是可以接受的。

弹出效果仅运行一次,并且在事件返回后,因此不会影响滚动。

抓住滚动事件的好主意,最好使用定时器,每隔几毫秒检查滚动位置,如果在你需要的范围内,那么执行你需要的必要代码

更新:在过去几年中,最佳做法是订阅活动并使用throttle避免过度处理https://lodash.com/docs#throttle