Go to anchor AFTER loading
Asked Answered
V

4

15

The Idea

I have a User Manual page, it is kinda big, and each topic has a anchor linked to it.

In my product page, I can link the client straight to that topic in the manual with a anchor, like:

Manual:

<a href="#manage_options">Managing Options</a>
<!-- Instructions on how to manage options -->

Product Page:

<a href="http://example.com/manual/#!/manage_options">How to Manage Options</a>

The Problem

When I click the "How to Manage Options" link in Product Page, it goes to the manual and immediately to the #manage_options anchor

But it often stops in the wrong place, because it goes to the anchor, then it keeps loading images, which changes the position of the content

Is it possible to wait for all the content to be loaded, then it goes to the anchor, or any better solution for this problem?

Vanesavanessa answered 9/3, 2013 at 22:2 Comment(0)
A
6

...it keeps loading images, which changes the position of the content

It's a best practice to explicitly declare your image sizes to avoid unnecessary repaints:

https://developers.google.com/speed/docs/best-practices/rendering#SpecifyImageDimensions

Specify image dimensions

Overview

Specifying a width and height for all images allows for faster rendering by eliminating the need for unnecessary reflows and repaints.

Details

When the browser lays out the page, it needs to be able to flow around replaceable elements such as images. It can begin to render a page even before images are downloaded, provided that it knows the dimensions to wrap non-replaceable elements around. If no dimensions are specified in the containing document, or if the dimensions specified don't match those of the actual images, the browser will require a reflow and repaint once the images are downloaded. To prevent reflows, specify the width and height of all images, either in the HTML tag, or in CSS.

Recommendations

Specify dimensions that match those of the images themselves. Don't use width and height specifications to scale images on the fly. If an image file is actually 60 x 60 pixels, don't set the dimensions to 30 x 30 in the HTML or CSS. If the image needs to be smaller, scale it in an image editor and set its dimensions to match (see Optimize images for details.) Be sure to specify dimensions on the image element or block-level parent Be sure to set the dimensions on the element itself, or a block-level parent. If the parent is not block-level, the dimensions will be ignored. Do not set dimensions on an ancestor that is not an immediate parent.

So use:

<img src="cat.jpg" alt="A Cat" width="360" height="200">

Or

<img src="cat.jpg" alt="A Cat" style="width:360px;height:200px;">

...or you can specify the dimensions in an external stylesheet, but generally that is more difficult with varying image sizes. This will ensure your content doesn't shift as images are loaded.

Atwekk answered 9/3, 2013 at 22:20 Comment(7)
Done. That's great, a simple solution that solved 80% of the problem! I have one more issue with it now => How do I prevent the page from scrolling back to TOP when finished loading? (usually in visitor's first visit) Is it possible?Vanesavanessa
Are you loading the content via AJAX? It seems to be the case by the looks of #!/manage_options, otherwise can you explain the !/ part? I'm not sure I understand why it would be scrolling back to the top, but generally a return false or event.preventDefault() is needed in the function that intercepts the click. That's probably your issue - it's looking for an anchor named !/manage_options and not finding it, therefore jumping to the top of the page as it would with something like <a href="#doesnt_exist">This</a>.Atwekk
We use this exact same structure, Documenter 1.6 => docs.revaxarts.com/doc_5abc94922c2f61e83ddda2d5e7112179Vanesavanessa
I don't get what the point of the hashbang #! is there, it actually changes the url http://domain/etc/#sources_and_credits into the hashbang version once it loads (you can even go forward a few steps, then click back to get to the original URL). I may be missing something but I think it's pointless vanity (Twitter does it, must be good, etc. etc). Anyways, did you try return false on the links? That page doesn't jump to the top like you say yours does. Maybe need to see more code.Atwekk
I think it doesn't jump to the top because it is really light, so it loads instantly. Try this: revaxarts-themes.com/documenter/docs/#!/what_else (clear cache if it doesn't bugs at once)Vanesavanessa
Even Better, made this extra-heavy version to better ilustrate: docs.revaxarts.com/doc_ead50d6febb1d23c9d4bc5d1d5b176bb/…Vanesavanessa
I think I see what you mean now, but I'm not sure how to correct it. I would try without the hashbang, but I'm not sure where in your scripts it's replacing the standard #hash_fragment.Atwekk
P
5

You can solve the problem using a JQuery script, this can postpone the anchor link after the page is loaded, i added an offset of 20 px also.

$(document).ready(function() {
    if(window.location.hash) {
        $('html, body').animate({
            scrollTop: $(window.location.hash).offset().top - 20
        }, 500);
    }
});
Phile answered 1/12, 2017 at 15:8 Comment(2)
Is it doable without JQuery?Hefter
document.getElementById(window.location.hash.substring(1)).scrollIntoView(); developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewMikiso
B
1
function moveToHash() {
    let urlHash = window.location.hash;

    if (urlHash) {
         window.location.hash = '';
         window.location.hash = urlHash;
    }
}

(Copied and fixed from https://mcmap.net/q/825534/-external-link-to-anchor-can-you-delay-scroll)

Beaner answered 22/4, 2022 at 14:3 Comment(0)
E
0

@boxed's answer works excellently when I execute the code in the developer tool console, but it doesn't work when I run from code without the developer tool. I don't know why.

@zod's answer is more fantastic (with smooth effect). The only caveat is it's using jQuery. So I changed it a little without using jQuery and tested it works very well!

The core is as follows:

const urlHash = window.location.hash;

if (urlHash) {
    const targetElement = document.querySelector(decodeURI(window.location.hash));

    if (targetElement) {
        var offset = 20;
        var targetOffset = targetElement.getBoundingClientRect().top + window.scrollY;
                
        window.scrollTo({
            top: targetOffset - offset,
            behavior: 'smooth' // 实现平滑滚动.   
        });
    }
}

The @chimeraha's comment also work, but it's better to add a decodeURI to make non ASCII hash to work:

- document.getElementById(window.location.hash.substring(1)).scrollIntoView();
+ document.getElementById(decodeURI(window.location.hash.substring(1))).scrollIntoView();
Enate answered 11/9, 2023 at 5:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.