简体   繁体   中英

position fixed div, when scrolling up and position absolute, when scrolling down: google now search bar type behavior

Im trying to create a div behavior very similar to google now's search bar control.

When the page loads initially, you get a div located in a specific position, as you start scrolling down the div will remain in its relative/absolute position(slide along with the scroll until it disappears). Once you start scrolling up (or page up) the div would slide in from the top(along with the content) until it reaches its fixed position and stay there.

Now Ive come up with a very crude/ugly example of what Im trying to achieve and it sort of works, but Im sure there's a far better approach in general to this.

http://jsfiddle.net/9654gd6c/3/

var lastScrollTop = 0,
    scrH = 40,
    marginTop = 40,
    ch = {};
$(window).scroll(function (event) {
    var st = $(this).scrollTop();

    var elements = $('#scroller');

    if (st > lastScrollTop) {
        elements.css({
            'position': 'absolute'
        });
        ch.dir = 'down';

    } else {

        if (ch.dir === 'down') ch.at = lastScrollTop;
        if (ch.at - st - marginTop > scrH) {
            elements.css({
                'position': 'absolute',
                    'top': st + marginTop
            });
        } else {
            elements.css({
                'position': 'absolute',
                    'top': ch.at - scrH
            });
        }
        ch.dir = 'up';

    }
    lastScrollTop = st;
});

oh and the remove style button should act as immediate show div button, that brings back the div to its fixed place. Thanks for your help in advance

Update 2 : Thanks to David Karam here's an example without switching the position
http://jsfiddle.net/rmx50du5/2/

The biggest downside to your implementation is the fact that you are switching between position fixed and absolute. This means you cannot make use of CSS animations which can come real handy in your example.

Here's a modified version with position relative allowing for use of transitions (I use opacity but you probably want to transition on top which will require a couple of extra lines to offset the scrolling)

http://jsfiddle.net/o16bebtu/

It is a neater way of achieving what you want by making the position relative and then making use of getBoundingClientRect which accounts for scrolling position.

var nodeScrollTop= ((Math.ceil(rect.top))|0);
var nodeTop= (!!(_node.style.top)) ? parseInt(_node.style.top) : 0;
var newNodeTop= nodeTop - nodeScrollTop;

From MDN, https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect

The amount of scrolling that has been done of the viewport area (or any other scrollable element) is taken into account when computing the bounding rectangle. This means that the top and left property change their values as soon as the scrolling position changes (so their values are relative to the viewport and not absolute). If this is not the desired behaviour just add the current scrolling position to the top and left property (via window.scrollX and window.scrollY) to get constant values independent from the current scrolling position.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM