为屏幕上的位置添加侦听器

时间:2011-01-26 17:44:23

标签: javascript jquery

我想在我的网站上设置一些东西,当你在页面底部的15%内滚动时,一个元素从侧面跳出来......我不知道如何开始这里...应该我为滚动函数添加了一个监听器吗?

我正在尝试在此页面底部重新创建效果: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()值没有改变。该页面是我的视口的两倍。

4 个答案:

答案 0 :(得分:6)

<强> [Working Demo]

$(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;
    }
  });
});

答案 1 :(得分:5)

我知道这是一个古老的主题,但上面收到复选标记的代码也触发了$(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文件。

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

答案 2 :(得分:3)

捕获滚动事件的好主意,最好使用定时器,每隔几毫秒检查一次滚动位置,如果在你需要的范围内,则执行所需的代码,然后执行所需的代码

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

答案 3 :(得分:3)

这样的事情应该有效:

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

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

另外,我们只需要 flyout 一次。所以我们可以在飞出后解开事件处理程序。

我们不希望 flyout 效果减慢滚动速度,因此我们将从事件循环中运行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,这是可以接受的。

弹出效果只运行一次,并且在事件返回后,所以它不会影响滚动。