简体   繁体   中英

Scroll to anchor position with fixed header

I have created a single page vertical scroll. When the user clicks on an anchor like "about" it will scroll to that position. Something to keep in mind is, that I use a fixed header with a height of 80px.

Above example works. When I click on "about us" with the anchor "about" it will scroll to the section with the id of "about". Nothing special.

But the problem is the following. When I say, I want to navigate visitors to a special place in the one page design. For example like this: www.mydomain.com/#about - it should scroll directly to that position, when entering above URL. But this I can't get work. I don't know how to explain this because there are a lot of scenarios that happens for me. Like it will scroll directly to the bottom page or it will scroll not specific to that section, it stops to late, or the position is not minus the header that results that the fixed header overlaps the content of that section. It's important that the target position is minus the fixed header.

Beside that I think that I am using unnecessary code for some parts. Some advice how to improve my code would also be nice.

A working code you can find here

Code: First part of my code. Here I control the click function. When the user clicks on a link inside #primary-navwrapper it should do that function. Store the asked hash link inside anchorId and set it to scrollToAnchor function. Then it gets the position of that hash decreased by the fixed header (so the header will not overlap the content). And update the hash with the current anchorId.

// An offset to push the content down from the top
    var offset = $('#header').outerHeight();


    // Navigation click action
    // Scroll to # HASH ID
    $('#primary-navwrapper li a[href^="#"]').click(function(event) {

        // Prevent from default action to intitiate
        event.preventDefault();

        // The id of the section we want to go to
        var anchorId = $(this).attr('href');

        scrollToAnchor(anchorId);

        return false;
    });


    function scrollToAnchor(anchorId) {

    // Our scroll target : the top position of the section that has the id referenced by our href
    var target = $(anchorId).offset().top - offset;
    //console.log("target" + target);

    // The magic...smooth scrollin' goodness.
    $('html, body').animate({ scrollTop: target }, 500, function () {
        //window.location.hash = '!' + id;
        window.location.hash = anchorId;
    });

}

Does someone has a solution for this or maybe some advice. Look out to your answer.

Casper

UPDATED ANSWER

This is the working code jsFiddle


PROBLEM SUMMARY

  1. When a user clicks one of the menus, screen will move to the content section, but it's too close to the header. There should be spaces between the content area and my header.
  2. I need to move screen to the expected content section when a user enters into my homepage with a query string like '#aboutus'

This is your core question I could understand so far, and I summarized this for the future helpers for you.

I thoroughly checked your codes and found some factors that don't bring you the result you expected.

First , there was no document.ready() scope. Everything was declared over global scopes. Well your functions seem to be okay in the global sections, but your click events should be declared in the document.ready() section so that jQuery properly takes them and initilizes them.

For this reason, your original code doesn't produce the animation when scrolling down to the expected section because it's the browser's default behaviour by href=# , not by your click event. So I added some of codes to ensure the event call.

And secondly , you didn't have any methods to scroll to the expected content section when your url has a query string like #gallery, #aboutus, and etc . So I put some codes for that

Please find my ID on the script sheet, then it will locate the exact points where I newly added or editted the existing codes. I commented a lot


FYI

There's a thing that I couldn't figure out. Your code is supposed to work nicely, but IE scrolls differently. Since you use event.preventDefault() on your click event, the default scrolling action by href=#something shouldn't work. But it does the behaviour in IE whereas chrome shows the expected result. ( what I'm telling you here is that the task to leave spaces for your sticky header )

I thought at first that this is the IE bug, but it wasn't. It should work like this example I made. well, I can't dig into this problem any further. It's your time.


OLD ANSWER

In this case, you need to get the query string and let your scrollToAnchor takes it at the $(document).ready() point.

var queryString = window.location.hash;    
scrollToAnchor(queryString);

I tested on your fiddle and it works.

And please make sure your scrollToAnchor doesn't throw an error because of an empty parameter. The emptry string "" and null object causes an error in your scrollToAnchor

Put a safeguard like this.

function scrollToAnchor(anchorId) {
    if ( anchorId == null || anchorId == "" ) {
        return false;
    }
    .
    .

But this safeguard also cannot prevent the error when a user mistyped querystring, like #avoutus which doesn't exist on your document. So I recommend you avoid $(anchorId).offset().top - offset; this kind of code.

Selecting an element directly via such dynamic variables can't gurantee a safe object unless they are totally under your control.

This worked for me.

html {
  scroll-padding-top: 70px; /* height of sticky header */
}

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