javascripthtmlasynchronous

linking to an anchor on a dynamically generated page


I have some pages that are largely constructed from a data file using javascript when the page loads. I discovered that anchors constructed as part of this weren't being recognized by the browsers - the page would just load but not go to the anchor. After some Internet searching, I found some javascript code samples that resolved the issue (almost).

My javascript code works when I test it but when I remove the feedback "alert", it stops working - that is, it behaves as it did without the code (the page loads but doesn't go to the anchor).

function setpage() {
   ...
   var target = location.hash.substring(1);
   ...
   if (target) {
      alert('scrolling to >' + target + '<');
      window.scrollTop = document.querySelector(target).offsetTop;
   }
}

The setpage function is executed in the body tag of each page on the site:

<body onload="setpage();">

which is why the test to see if an anchor is the target. The page may be accessed without an internal anchor being referenced. setpage includes more code but this is the only relevant part.

With the alert function in place, the alert shows me the anchor. When I close the alert, the javacript generates the dynamic part of the page (while the alert window is open, the page behind it just shows the static elements in the page) then goes to the anchor location.

I thought initially that perhaps the page was being generated in the background and the alert was merely stopping it from showing. So I put the window.scrollTop into a setInterval function to delay the execution.

setTimeout(function() {
    window.scrollTop = document.querySelector(target).offsetTop;
}, 6000);

but that didn't have any impact. It still works if the alert is in place but fails when it isn't.

I do note that it always works with static anchors.


Solution

  • The issue you're experiencing is likely related to timing—the JavaScript is trying to scroll to the anchor before the dynamic content has fully rendered. The alert effectively acts as a delay, allowing the page to finish rendering before the scroll executes. Without the alert, the script runs too soon, and the target element doesn't exist or isn't fully positioned yet.

    Here’s how to address the problem:

    Fix with DOMContentLoaded or Dynamic Content Check You need to ensure that the anchor scrolling happens after the dynamic content is fully loaded. Since your page is dynamically constructed, waiting for DOMContentLoaded alone may not suffice—you may need to wait until the specific target element is present in the DOM.

    Updated Code Replace your window.scrollTop logic with the following approach:

    function setpage() {
    var target = location.hash.substring(1); // Get the anchor name
    if (target) {
        // Use a small delay to ensure content is rendered
        setTimeout(function checkAndScroll() {
            var targetElement = document.querySelector(`#${target}`);
            if (targetElement) {
                // Scroll to the element once it exists
                targetElement.scrollIntoView({ behavior: "smooth" });
            } else {
                // If the element isn't found yet, retry after a short delay
                setTimeout(checkAndScroll, 100);
            }
        }, 100);
    }
    

    }