最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Slide header up if you scroll down and vice versa - Stack Overflow

programmeradmin0浏览0评论

Update

I made a repo on GitHub:

.js

Big thanks to Sargo Darya and Edward J Payton.


I've to create a header which slides up if you scroll down and vice versa. The problem is, that it jumps (if you are in the diff-range between 0-128).

I can not figure out where the problem sits. Any idea how to get this to work correctly?

Here's what I've done so far: /

// something simple to get the current scroll direction
// false === down | true === up
var scrollDir = (function (oldOffset, lastOffset, oldDir) {
    return function (offset) {
        var dir = offset < oldOffset;
        if (dir !== oldDir) lastOffset = offset;
        oldOffset = offset;
        oldDir = dir;
        return {dir: dir, last: lastOffset};
    };
}());

var header = document.querySelector('header');
var height = header.clientHeight;
addEventListener('scroll', function () {
    var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
    var dir = scrollDir(scrollY);
    var diff = dir.last-scrollY;

    var max = Math.max(-height, Math.min(height, diff));
    header.style.top = (dir.dir ? max-height : max) + 'px';
});

Another problem is, that if the scroll-direction was changed the first time, nothing happens. However, this could be fixed with an interval, or else.

Update

I made a repo on GitHub:

https://github./yckart/Veil.js

Big thanks to Sargo Darya and Edward J Payton.


I've to create a header which slides up if you scroll down and vice versa. The problem is, that it jumps (if you are in the diff-range between 0-128).

I can not figure out where the problem sits. Any idea how to get this to work correctly?

Here's what I've done so far: http://jsfiddle/yckart/rKW3f/

// something simple to get the current scroll direction
// false === down | true === up
var scrollDir = (function (oldOffset, lastOffset, oldDir) {
    return function (offset) {
        var dir = offset < oldOffset;
        if (dir !== oldDir) lastOffset = offset;
        oldOffset = offset;
        oldDir = dir;
        return {dir: dir, last: lastOffset};
    };
}());

var header = document.querySelector('header');
var height = header.clientHeight;
addEventListener('scroll', function () {
    var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
    var dir = scrollDir(scrollY);
    var diff = dir.last-scrollY;

    var max = Math.max(-height, Math.min(height, diff));
    header.style.top = (dir.dir ? max-height : max) + 'px';
});

Another problem is, that if the scroll-direction was changed the first time, nothing happens. However, this could be fixed with an interval, or else.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Sep 4, 2013 at 1:27 yckartyckart 33.5k9 gold badges126 silver badges133 bronze badges 4
  • can you use jQuery? it's in your tag but you don't use it in jsfiddle? – BMH Commented Sep 4, 2013 at 10:48
  • @BMH Sure, no problem! I had jQuery as dependency, but there was no need for it yet. – yckart Commented Sep 4, 2013 at 10:56
  • Just my thought, it should be easier to use jQuery function to show and hide the header, you just need to identify the direction. But with jQuery the mystery of this question is not revealed, is it? ;) – BMH Commented Sep 4, 2013 at 11:11
  • No, not really :P See my first approach: fiddle.jshell/cMnVq <= Looks good, but my client doesn't think so :( – yckart Commented Sep 4, 2013 at 11:14
Add a ment  | 

3 Answers 3

Reset to default 4 +50

I believe this is exactly what you want:

var header = $('header'),
headerHeight = header.height(),
treshold = 0,
lastScroll = 0;

$(document).on('scroll', function (evt) {
    var newScroll = $(document).scrollTop(),
        diff = newScroll-lastScroll;

    // normalize treshold range
    treshold = (treshold+diff>headerHeight) ? headerHeight : treshold+diff;
    treshold = (treshold < 0) ? 0 : treshold;

    header.css('top', (-treshold)+'px');

    lastScroll = newScroll;
});

Demo on: http://jsfiddle/yDpeb/

Try this out:- http://jsfiddle/adiioo7/rKW3f/7/

JS:-

var scrollDir = (function (oldOffset, lastOffset, oldDir) {
    return function (offset) {

        var dir = offset < oldOffset;
        if (dir !== oldDir) {
            lastOffset = offset;
        } else {
            offset = offset - height;
        }
        oldOffset = offset;
        oldDir = dir;
        return {
            dir: dir,
            last: lastOffset
        };
    };
}());

var header = document.querySelector('header');
var height = header.clientHeight;

$(window).scroll(function () {
    var scrollY = $(window).scrollTop();
    var dir = scrollDir(scrollY);
    var diff = dir.last - scrollY;

    var max = Math.max(-height, Math.min(height, diff));

    max = (dir.dir ? max - height : max); 
    max = scrollY<height?0:max;


    $('header').data('size', 'small');
    $('header').stop().animate({
        top: max
    }, 600);


});

Sargo Darya's answer above is exacty what i was looking for but I found a bug with Webkits inertia scrolling so I made a fix:

// Scrolling Header
var header = $('header'),
headerHeight = header.height(),
offset = 0,
lastPos = 0;

$(document).on('scroll', function(e) {
var newPos = $(document).scrollTop(),
    pos = newPos-lastPos;

if (offset+pos>headerHeight) { 
    offset = headerHeight;
} else if (newPos < 0){ // webkit inertia scroll fix
    offset = 0;
} else {
    offset = offset+pos;
};
if (offset < 0) {
    offset = 0;
} else {
    offset = offset;
};

header.css('top', (-offset)+'px');

lastPos = newPos;
});

Adding one line fixed it. If - if scroll position is lower than 0, set header offset at 0.

Demo based on Sargo Darya's - http://jsfiddle/edwardomni/D58vx/4/

发布评论

评论列表(0)

  1. 暂无评论