Question

I have a problem with my menu and my navigation based on #anchors. I'm using a JS function to sick my menu to top when scrolling (#stickyheader). there's a div upon my menu that disappear when scrolling (#unstickyheader). the height of this div is not fixed, it will depend of its content lengths and also of the width of the screen. my menu links to vertically to different parts of my page, in my js function handling the anchors navigation, I have an offset value, to display my section's title with a defined padding under my menu :

$target.offset().top-90

here is my css :

html,body{padding:0;margin:0;font-family: Helvetica, Geneva, Arial sans-serif;font-size:16px;;color: black;line-height: 24px;color: black;text-transform: lowercase;letter-spacing: 1px;background-color: white}

#wrapper{margin-left: 30px;margin-right: 30px;padding-bottom: 20px;}
#entry{position: relative}
#stickyheader { width: 100%;padding-top:10px;top: 0;z-index: 1000;background-color: white;padding-bottom: 10px;line-height: 24px;}
#unstickyheader {height:auto;padding-top:20px;}
.page{min-height: 3000px}
.separation{height: 600px;
background-color: white;
width: 100%;
margin-top: 300px;
margin-bottom: 300px;}

my html :

<div id="wrapper">
    <div id="unstickyheader">
        <div class="bloc_bio">

        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor dignissim mollis. Nam tempor tristique ultricies. Nullam blandit aliquet augue, et elementum elit. Morbi at enim ut magna semper varius. Curabitur purus turpis, condimentum at ullamcorper vel, adipiscing vel enim. Phasellus hendrerit semper nisi quis molestie. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur egestas nibh nunc, ac facilisis dui ultricies eget. Integer vestibulum ultricies diam, ut laoreet risus. Morbi suscipit venenatis tortor sit amet faucibus. Ut eu justo elementum, ultrices elit in, eleifend enim.
        </div>
    </div>

    <div id="stickyheader">
        <a href="#disco">discography</a><span class="grey"> - </span>
        <a href="#bio">biography</a><span class="grey"> - </span>
        <a href="#press">press</a><span class="grey"> - </span>
        <a href="#studio">studio</a><span class="grey"> - </span>
        <a href="#contacts">contacts</a> 
    </div>

    <div id="entry">

        <div class="page">
        <div class="separation"></div>
            <div id="disco" class="ancre"></div>
            <div class="bloc_bio">
                <div class="legende">DISCOGRAPHY</div>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor dignissim mollis. Nam tempor tristique ultricies. Nullam blandit aliquet augue, et elementum elit. Morbi at enim ut magna semper varius. Curabitur purus turpis, condimentum at ullamcorper vel, adipiscing vel enim. Phasellus hendrerit semper nisi quis molestie. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur egestas nibh nunc, ac facilisis dui ultricies eget. Integer vestibulum ultricies diam, ut laoreet risus. Morbi suscipit venenatis tortor sit amet faucibus. Ut eu justo elementum, ultrices elit in, eleifend enim.
            </div>
            <div class="separation"></div>

            <div id="bio" class="ancre"></div>
            <div class="bloc_bio">
                <div class="legende">BIOGRAPHY</div>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor dignissim mollis. Nam tempor tristique ultricies. Nullam blandit aliquet augue, et elementum elit. Morbi at enim ut magna semper varius. Curabitur purus turpis, condimentum at ullamcorper vel, adipiscing vel enim. Phasellus hendrerit semper nisi quis molestie. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur egestas nibh nunc, ac facilisis dui ultricies eget. Integer vestibulum ultricies diam, ut laoreet risus. Morbi suscipit venenatis tortor sit amet faucibus. Ut eu justo elementum, ultrices elit in, eleifend enim.
            </div>
            <div class="separation"></div>

            <div id="press" class="ancre"></div>
            <div class="bloc_bio">
                <div class="legende">PRESS</div>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor dignissim mollis. Nam tempor tristique ultricies. Nullam blandit aliquet augue, et elementum elit. Morbi at enim ut magna semper varius. Curabitur purus turpis, condimentum at ullamcorper vel, adipiscing vel enim. Phasellus hendrerit semper nisi quis molestie. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur egestas nibh nunc, ac facilisis dui ultricies eget. Integer vestibulum ultricies diam, ut laoreet risus. Morbi suscipit venenatis tortor sit amet faucibus. Ut eu justo elementum, ultrices elit in, eleifend enim.
            </div>
            <div class="separation"></div>

            <div id="studio" class="ancre"></div>
            <div class="bloc_bio">
                <div class="legende">STUDIO</div>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor dignissim mollis. Nam tempor tristique ultricies. Nullam blandit aliquet augue, et elementum elit. Morbi at enim ut magna semper varius. Curabitur purus turpis, condimentum at ullamcorper vel, adipiscing vel enim. Phasellus hendrerit semper nisi quis molestie. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur egestas nibh nunc, ac facilisis dui ultricies eget. Integer vestibulum ultricies diam, ut laoreet risus. Morbi suscipit venenatis tortor sit amet faucibus. Ut eu justo elementum, ultrices elit in, eleifend enim.
            </div>
            <div class="separation"></div>

        </div>
    </div>
</div>

and the javascript :

$(function(){
        // Check the initial Poistion of the Sticky Header
        var stickyHeaderTop = $('#stickyheader').offset().top;

        $(window).scroll(function(){
                if( $(window).scrollTop() > stickyHeaderTop ) {
                        $('#stickyheader').css({position: 'fixed', top: '0px'});
                        $('#stickyalias').css('display', 'block');
                } else {
                        $('#stickyheader').css({position: 'static', top: '0px'});
                        $('#stickyalias').css('display', 'none');
                }
        });
  });

//-------------------------------------------------- # SCROLL ----------------------------------------------------//            

$(document).ready(function(){
    $('a[href^="#"]').bind('click.smoothscroll',function (e) {
        e.preventDefault();

        var target = this.hash,
        $target = $(target);

        $('html, body').stop().animate({
            'scrollTop': $target.offset().top-90
            //--OFFSET--//
        }, 2000, 'swing', function () {
            window.location.hash = target;
        });
    });
});

my problem is that I need this offset to be dynamically generated. On each click of any item from my menu the offset need to check if my menu (#stickyheader) is sticked to the top of my page, and then calculate the height of my menu (#stickyheader), this will be the offset (+10px for padding-bottom). if my menu is not sticked to top, so the div uppon my menu is displayed (#unstickyheader), the offset should be the height of my menu (#stickyheader) + the height of the div (#unstickyheader).

I don't know how I can calculate the total heights of the two divs, depending if the first div is displayed, and also to calculate at every click in my menu...

what do you think of that ? is there another solution ?

I've made a JSfiddle here, http://jsfiddle.net/uFq2k/359/

the offset in the example is 90, so when my I click on a menu item when my div (#unstickyheader) is displayed, the padding between my menu and my section title, for example "discography" is right, but when I click on another link after that, let's say biography, the padding is to big...should be around 50...

I really hope you understand my question, it's hard for me to explain, but if you test my JSfiddle you should understand the issue.

thanks a lot for your help !

Was it helpful?

Solution

I believe this is what you want: http://jsfiddle.net/B5dYv/

The problem was that #stickyheader was switching between fixed and other display value. This caused the other elements offset to change because the fixed effectively removes the element from the dom stack which ultimately caused the wrong scroll value.

What I did was instead of switching #stickyheader between static and fixed, it is now relative and fixed.

Also, the main fix to the scrolling problem was to conditionally set the scroll offset by checking the position of #stickyheader and the height, thus the dynamic offset you wanted.

$(document).ready(function () {
    $('a[href^="#"]').bind('click.smoothscroll', function (e) {
        e.preventDefault();

        var target = this.hash,
            $target = $(target);

        var offset;
        if($('#stickyheader').css('position') == 'relative'){
            offset = $('#stickyheader').outerHeight(true)*2;
        }else{
            offset = $('#stickyheader').outerHeight(true);
        }
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top - offset
            //--OFFSET--//
        }, 2000, 'swing', function () {
            window.location.hash = target;
        });
    });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top