

Ask HN: How do you create a "limited fixed div"? - unalone

I feel a bit embarrassed asking an HTML/JavaScript question, but this is tough because I don't know exactly how you'd describe this effect easily.<p>What I'm looking to do is create a div that moves along with the user's scrolling - exactly how a fixed div does - but that only does so within the confines of a certain space. I have a site design that's split into two pieces. I want the div to move within the top space, stop when it gets to the bottom space. After that it quits moving down.<p>How would I get this to work? The problem is, I'm not at all familiar with using JavaScript to manipulate physical location, so I'm not certain how exactly I'd make this solution. And, to the best of my knowledge, this isn't something that HTML/CSS can do on its own: fixed is all-or-nothing.
======
qhoxie
I did this in jQuery at one time. Hopefully this is helpful.

    
    
      $(window).scroll(function() {
        var offsetTop = $(window).scrollTop();
        $("#target").css({top: offsetTop});
      });
    

To explain, whenever the viewport is scrolled, the offset of the viewport to
the top of the page is set (offsetTop). Then the #target element is moved to
follow the viewport. That will give a fixed effect, so what you need to do is
set the max offsetTop to (max depth - #target height).

 _Note:_ Dimension type calculations vary widely among browsers, so using a
library like jQuery dimensions is quite helpful.

~~~
davidjeffries
+1 for jQuery dimensions. That plugin is a godsend for doing things like this.

~~~
sam_in_nyc
scrollTop(), offset(), and the like are built in to the latest jQuery.

I love jQuery.

------
jreposa
Here's a smooth scrolling div within boundaries based on a timeout.

    
    
      var attrs = {};
      $(document).ready(function(){
        attrs.startY = $("#target").offset().top;
    
        // pad the bottom by 20 pixels including the 20 pixels from top added in fixed()
        attrs.endY = $('#bottom').offset().top - $("#target").height() - 40;
    
        var t = null;
        $(window).scroll(function(){
          clearTimeout(t);
          t = setTimeout('fixed()', 500);
        });
      });
    
      function fixed() {
        var offsetTop = $(window).scrollTop();
        if (offsetTop < attrs.startY) {
          offsetTop = attrs.startY-20; // get rid of 20 pixel padding when at the top
        } else if (offsetTop > attrs.endY) {
          offsetTop = attrs.endY;
        }
        $("#target").animate({top: offsetTop+20}, 500); // add 20 pixel padding from the top
      }

~~~
unalone
Smooth scrolling meaning there's no jump, right? Or meaning it
accelerates/decelerates?

------
calvin
If you use Prototype, you'll want to look at the API docs for
document.viewport and getHeight

\-- <http://www.prototypejs.org/api/document/viewport>

\-- <http://www.prototypejs.org/api/element/getheight>

------
zacharydanger
I'd recommend posting this question over at stackoverflow.com, too.

~~~
unalone
I did, and got nothing useful back. Oh well, maybe next time.

------
HendrikR
There's an article discussing this topic on ajaxian.com featuring another
jQuery solution: <http://ajaxian.com/archives/pegs-automate-display-fixed>

