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

javascript - Reliably jumping to named anchor on dynamically generated page? - Stack Overflow

programmeradmin3浏览0评论

I have a web page which is dynamically built by the client. It generates dozens of list items each with its own named anchor. The side of the page has a fixed table of contents (TOC) with hyperlinks that point to the named anchors. This allows the user to click a TOC entry a jump to the item.

The trouble I am encountering is that on the initial page load the page is dynamically generated and so it cannot scroll to the item in the initial hash of the URL using the default behavior of a browser. Additionally, when the user switches to a different book the page is pletely regenerated with new content and a new starting hash. Same problem: since the hash preexists the content, it doesn't situate itself with the item already in view.

I nearly solved this with JavaScript by awaiting the rendering and then jumping to the hash using scrollIntoView method on the appropriate element.

The next problem is that the stylesheet is not fully applied by the time scrollIntoView is called and so the final position of the item is unknown. I see the unstyled item scroll into view, but once styling is applied the positioning is lost. I put a 1 second setTimeout in place to delay the scrollIntoView call. This works but feels fragile.

Are there reliable techniques for jumping to a named anchor when the content es after the hash is in place? If I knew when the CSS was done styling content that might help. Alternately, it might be useful to trigger an event once the height of the page stabilizes (thus signaling the finalization of CSS styling).

I have a web page which is dynamically built by the client. It generates dozens of list items each with its own named anchor. The side of the page has a fixed table of contents (TOC) with hyperlinks that point to the named anchors. This allows the user to click a TOC entry a jump to the item.

The trouble I am encountering is that on the initial page load the page is dynamically generated and so it cannot scroll to the item in the initial hash of the URL using the default behavior of a browser. Additionally, when the user switches to a different book the page is pletely regenerated with new content and a new starting hash. Same problem: since the hash preexists the content, it doesn't situate itself with the item already in view.

I nearly solved this with JavaScript by awaiting the rendering and then jumping to the hash using scrollIntoView method on the appropriate element.

The next problem is that the stylesheet is not fully applied by the time scrollIntoView is called and so the final position of the item is unknown. I see the unstyled item scroll into view, but once styling is applied the positioning is lost. I put a 1 second setTimeout in place to delay the scrollIntoView call. This works but feels fragile.

Are there reliable techniques for jumping to a named anchor when the content es after the hash is in place? If I knew when the CSS was done styling content that might help. Alternately, it might be useful to trigger an event once the height of the page stabilizes (thus signaling the finalization of CSS styling).

Share Improve this question asked Mar 31, 2016 at 15:30 M. LanzaM. Lanza 6,8003 gold badges45 silver badges77 bronze badges 6
  • When you say "jump to", do you mean focus? .and, is "hash" an element on the page you're wishing to focus? and if so, will it always have the same name? – M.Bush Commented Mar 31, 2016 at 15:35
  • The content exceeds the viewport and so the item deserving to appear at the top of the viewport (per the hashtag in the URL) needs to be scrolled into view. The names remain unchanged. – M. Lanza Commented Mar 31, 2016 at 15:38
  • I edited my answer about focusing, with a link to jquery.scrollTo – M.Bush Commented Mar 31, 2016 at 15:41
  • I see no good answers have been given.. To do that you would need to add event listeners for "resize" and "load" events, and I guess another one for the "scroll" event in order to disable your programmatic scroll if the user starts scrolling after the page navigation and before the content got fully loaded. – Shautieh Commented Jul 3, 2023 at 9:56
  • @Mario: Did you ever manage to sort this out? I'm in a similar situation and need to solve the same problem. – Tomas Eklund Commented Feb 8, 2024 at 7:18
 |  Show 1 more ment

4 Answers 4

Reset to default 7

I had a similar problem, although in my case only the table of contents and named anchors were autogenerated in the onload handler - not the rest of the page content. I solved the initial hash problem by adding the following code to my onload handler after generating the anchors:

if (location.hash)
{
    var requested_hash = location.hash.slice(1);
    location.hash = '';
    location.hash = requested_hash;
}

I had to set the hash to '' before setting it back to the requested name to make the browser respond. This seemed to work in all the browsers I tried (Opera, Chrome, Edge, IE, FF).

I encountered the same problem. A lot of the page was loaded dynamically, after the document's onload event had fired, and navigating to a given anchor on the page did not work properly. The visitor usually landed at a "random" position on the page and the intended target had been pushed way out of the viewport by dynamically added content that preceded it in the document.

This is how I solved it:

(function() {
    var targetElement = document.querySelector(window.location.hash);
    if (targetElement) {
        var stayInPlace = function() {
            targetElement.scrollIntoView();
        };
        var observer = new ResizeObserver(stayInPlace);
        var stopObserving = function() {
            observer.disconnect();
        };
        
        observer.observe(document.querySelector('main'));
        window.addEventListener('wheel', stopObserving, {once: true});
        window.addEventListener('touchstart', stopObserving, {once: true});
    }
})();

I'm using the ResizeObserver API (available since circa 2018) to detect changes to the size of the <main> element. In my case the target and the dynamically loaded elements were all children of the main element. Adjust if needed. On each size change we make sure to scroll the requested target into view.

Whenever the user starts interacting with the page, using either the scroll wheel or touch, we stop observing and forcibly adjusting the scroll position. I was not able to figure out how to detect usage of the scrollbars.

You can use jQuery if you will always know the name of the element you want to set focus to. You can run this after your page has loaded:

$( "#targetElementGoesHere" ).focus();

Edit: To scroll to that, check out https://github./flesler/jquery.scrollTo

I think the answer you require was answered by this guy...

How to wait until a web page is loaded with javascript?

So, something like this...

document.onload = function(){ 
    scrollIntoView...
}
发布评论

评论列表(0)

  1. 暂无评论