简体   繁体   中英

Preventing anchor from jumping on page load

I'm currently using 'smooth scroll' on my wordpress page, and I'm attempting to have the page smoothly scroll to the requested section when coming from an external link (using anchors ( #portfolio )from there I want the page to start at the top and THEN scroll to the portfolio section.

What's happening is it briefly displays the 'portfolio section' (anchor jump) and THEN resets to the top and scrolls down.

Code

$(function() {
    $('.menu li a').click(function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
    var target = $(this.hash);
    target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
    if (target.length) {
        $root.animate({
        scrollTop: target.offset().top - 75
        }, 800, 'swing');
            return false;  
            }
        }
    });
});

page load

$(window).on("load", function() {
if (location.hash) { // do the test straight away
    window.scrollTo(0, 0); // execute it straight away
    setTimeout(function() {
    window.scrollTo(0, 0); // run it a bit later also for browser compatibility
    }, 1);
}
var urlHash = window.location.href.split("#")[1];
if (urlHash && $('#' + urlHash).length)
    $('html,body').animate({
    scrollTop: $('#' + urlHash).offset().top - 75
    }, 800, 'swing');
});

How do I prevent the 'jumping' that seems to happen on page load?

HTML - nav links (using dummy links)

<a href="link.com/#portfolio>portfolio</a>

HTML - divs

<div id="portfolio></div>

You can circumvent the browser behavior by changing the anchor so that it carries some additional text that will be unique to the page visit. In the example below, I've added the first six lines to your function to set the AnchorSeed variable, and then I've used that variable where you assign the urlHash variable:

$(window).on("load", function() {
    var AnchorSeed = new Date() * 1;
    $( ".AnchorUpdate" ).each(
        function() {
            $( this ).attr( "id", this.id + AnchorSeed );
        }
    );
    if (location.hash) { // do the test straight away
        window.scrollTo(0, 0); // execute it straight away
        setTimeout(function() {
            window.scrollTo(0, 0); // run it a bit later also for browser compatibility
        }, 1);
    }
    var urlHash = window.location.href.split("#")[1] + AnchorSeed;
    if (urlHash && $('#' + urlHash).length)
        $('html,body').animate({
        scrollTop: $('#' + urlHash).offset().top - 75
        }, 800, 'swing');
});

And you'll need to add the AnchorUpdate class to any page element that you might jump to, so that the jQuery routine can find it and update its id with the AnchorSeed value. In this case, we know that "portfolio" is such a link, so it would be modified as:

<div class="AnchorUpdate" id="portfolio></div>

The effect of this is that the id will change from "portfolio" to something like "portfolio1382124849780" (depending, of course, on the time stamp when the page was loaded).

Because the id "portfolio" won't exist when the page finishes loading (even though it is part of the source HTML), the browswer shouldn't bounce to it.

I used JavaScript entirely because I didn't know if you had access to server variables. If you do, I think they might be a preferable solution, as the code will be more readable. You might use a page counter variable, or simply a server-side timestamp, if possible.

Edit:

In the comments you mentioned that this was working for external links, but that it broke internal links. I don't have time to set up a test right now, but I think it would work to add a jQuery routine to update those internal links similar to what is being done above. For example, your internal link is:

<a href="#InternalLink">Jump to Internal Link</a>

You might give it a different class indicating that it needs updating:

<a class="InternalLinkUpdate" href="#InternalLink">Jump to Internal Link</a>

And then trigger a similar modification of that class using jQuery:

$( ".InternalLinkUpdate" ).each(
    function() {
        $( this ).attr( "href", $( this ).attr( "href" ) + AnchorSeed );
    }
);

(Since I'm not able to copy from working code at the moment, I might have made a punctuation error or such in the above -- but it shouldn't take too much tinkering to get it to work properly.

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