Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding listener for position on screen

I'd like to set something up on my site where when you scroll within 15% of the bottom of the page an element flyouts from the side... I'm not sure how to get started here... should I add a listener for a scroll function or something?

I'm trying to recreate the effect at the bottom of this page: http://www.nytimes.com/2011/01/25/world/europe/25moscow.html?_r=1

update

I have this code....

     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() {

   });
     }

the console.log() values aren't changing when I scroll to the bottom of the page. The page is twice as long as my viewport.

like image 376
Webnet Avatar asked Jan 26 '11 17:01

Webnet


2 Answers

[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;
    }
  });
});
like image 140
25 revs, 4 users 83% Avatar answered Sep 26 '22 01:09

25 revs, 4 users 83%


I know this is an old topic, but the above code that received the check mark was also triggering the $(window).scroll() event listener too many times.

I guess twitter had this same issue at one point. John Resig blogged about it here: 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.');
    }
});

So the difference between the two blocks of code is when and how the timer is called. In this code the timer is called off the bat. So every 30 millaseconds, it checks to see if the page has been scrolled. if it's been scrolled, then it checks to see if we've passed the point on the page where we want to show the hidden content. Then, if that checks true, the actual function then gets called to show the content. (In my case I've just got a console.log print out in there right now.

This seems to be better to me than the other solution because the final function only gets called once per iteration. With the other solution, the final function was being called between 4 and 5 times. That's got to be saving resources. But maybe I'm missing something.

like image 45
Brent Avatar answered Sep 25 '22 01:09

Brent