skip to Main Content

I have a website where I’m using an iframe from a third-party company. The iframe is placed within a div with the ID "iframe". The problem I’m facing is that when the user clicks on any button in the iframe it reloads my whole page, the scroll position resets to the top. As a result, the user needs to scroll down again to see the updated content, which is not ideal. Additionally user doesn’t even suspect that something has happened, because the iframe is placed into the second section of website.

I’ve tried using JavaScript to scroll to the second section containing the iframe after it finishes loading. However, I haven’t been successful so far.

And I’m not certain if it was the right approach. I’ve attempted to use this code (it was provided by other person). But after iFrame is reloaded the new position is set to "0":

    Saved scroll position: 0
    Iframe reloaded

Probably the code must be triggered only on a lick in the iFrame, the links have some common patterns in the beginning.

Here’s the code I’m currently using:

window.onload = function() {
  var iframeContainer = document.getElementById("iframe");
  var iframe = iframeContainer.querySelector("iframe");
  var iframeSrc = iframe.getAttribute("src");

  console.log("Page loaded");

  // Check if there is a stored scroll position in the URL and restore it
  var scrollPosition = getScrollPositionFromUrl();
  if (scrollPosition) {
    window.scrollTo(0, scrollPosition);
    console.log("Restored scroll position:", scrollPosition);
  }

  // Save the scroll position in the URL when the user scrolls
  window.addEventListener("scroll", function() {
    var scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
    setScrollPositionToUrl(scrollPosition);
    console.log("Saved scroll position:", scrollPosition);
  });

  // Modify the iframe code to remove scroll position from the URL on reload
  iframe.addEventListener("load", function() {
    removeScrollPositionFromUrl();
    console.log("Iframe reloaded");
  });

  // Function to retrieve scroll position from URL
  function getScrollPositionFromUrl() {
    var hash = window.location.hash;
    if (hash) {
      var scrollPosition = parseInt(hash.substring(1));
      if (!isNaN(scrollPosition)) {
        return scrollPosition;
      }
    }
    return null;
  }

  // Function to set scroll position to URL
  function setScrollPositionToUrl(scrollPosition) {
    var hash = "#" + scrollPosition;
    history.replaceState(null, null, hash);
  }

  // Function to remove scroll position from URL
  function removeScrollPositionFromUrl() {
    history.replaceState(null, null, window.location.pathname);
  }
};


I would appreciate any help on how to resolve this issue. How can I ensure that the page automatically scrolls to the second section containing the iframe after it finishes loading? Thank you in advance for your assistance!

UPDATE

I have simplified the approach: try to check if the URL contains a common pattern and then manipulate the scroll position accordingly (use a hash link). However, this approach did not work consistently, and the scroll position was not properly restored after a page reload.

What is important, I discovered that the main page does not reload completely when a link within an iframe is clicked. So main page’s URL is updated with the new address after iFrame reload and scroll is taking me to top. As a result, the code I implemented did not have a chance to execute when the URL changed.

Here what I have tried:

window.addEventListener("load", function() {
  var iframeContainer = document.getElementById("iframe");
  var iframe = iframeContainer.querySelector("iframe");
  var commonUrlPattern = "/?step=index/step3"; // Update the common URL pattern as needed

  console.log("Page loaded");

  // Check if the URL contains the common pattern and the iframe has loaded
  if (window.location.href.includes(commonUrlPattern)) {
    console.log("Common URL pattern found");
    scrollToSection();
  }

  // Function to scroll to the custom section
  function scrollToSection() {
    // Replace 'section-id' with the actual ID of the section you want to scroll to
    var sectionId = "section-id";
    var sectionElement = document.getElementById(sectionId);
    if (sectionElement) {
      sectionElement.scrollIntoView({ behavior: "smooth" });
    }
  }

  // Listen for iframe load event to track URL changes within the iframe
  iframe.addEventListener("load", function() {
    console.log("Iframe loaded");
    var iframeUrl = iframe.contentWindow.location.href;
    if (iframeUrl.includes(commonUrlPattern)) {
      console.log("Common URL pattern found within iframe");
      scrollToSection();
    }
  });
});

2

Answers


  1. Chosen as BEST ANSWER

    I've used this code, it seems working, but if someone could suggest improved code, I will appreciate it:

    
      // Define the common URL pattern to match against
      var commonUrlPattern = "/?step=index/step3";
    
      // Function to get the current URL
      function getCurrentURL() {
        return window.location.href;
      }
    
      // Store the initial URL
      var initialUrl = getCurrentURL();
    
      // Store the current URL
      var currentUrl = initialUrl;
    
      // Function to check for URL changes
      function checkURLChange() {
        // Get the previous URL
        var previousUrl = currentUrl;
    
        // Get the current URL
        currentUrl = getCurrentURL();
    
        if (currentUrl !== previousUrl) {
          // alert("URL changed:nPrevious URL: " + previousUrl + "nCurrent URL: " + currentUrl);
    
          // Check if the URL matches the common pattern
          var isCommonUrl = currentUrl.includes(commonUrlPattern);
    
          if (isCommonUrl) {
            // alert("Common URL pattern found");
            // Perform the desired action or function here
            // For example, scroll to a specific section
            scrollToSection();
          } else {
            // alert("Common URL pattern not found");
          }
        }
      }
    
      // Function to scroll to a specific section
      function scrollToSection() {
        // Your code to scroll to the desired section goes here
        // For example:
        var targetElement = document.getElementById("iframe");
        if (targetElement) {
          targetElement.scrollIntoView({ behavior: "smooth" });
        }
      }
    
      // Check if the initial URL matches the common pattern
      var isInitialUrlCommon = initialUrl.includes(commonUrlPattern);
      if (isInitialUrlCommon) {
        // alert("Common URL pattern found initially");
        // Perform the desired action or function here
        // For example, scroll to a specific section
        scrollToSection();
      } else {
        // alert("Common URL pattern not found initially");
      }
    
      // Periodically check for URL changes
      setInterval(checkURLChange, 1000); // Adjust the interval as needed (in milliseconds)
    
    
    

  2. The modern way would be to create a custom event and then trigger that as needed.

    Here I set up the hash change event handler to do just that (not triggered here in this snippet)

    I also created a "test" that triggers it here as a snippet to see the scroll effect for this sample only.

    This is somewhat artificial but I think you can build from this.

    Reference: https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events
    Hash change ref:
    https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event

    const attachTo = '.bigger-is-me';//could be any element
    const targetEventElement = document.querySelector(attachTo);
    targetEventElement.dataset.scrollTarget = "#targetId";
    targetEventElement.dataset.pattern = "/?step=index/step3";
    
    // just for this example here!
    const testThisExample = "https://stacksnippets.net/js"
    targetEventElement.dataset.pattern = testThisExample
    
    //so we can see this in the event handler we pass it
    const details = {
      pattern: targetEventElement.dataset.pattern,
      seeme: targetEventElement.dataset.scrollTarget
    };
    
    //create custom event with our details from above
    const customEventScroll = new CustomEvent("scrollToSomething", {
      detail: details
    });
    
    function scrollToSection(targetElement) {
      targetElement.scrollIntoView({
        behavior: "smooth"
      });
    }
    
    function customEventHandler(ev) {
      //  console.log(`The pattern is: ${ev.detail.pattern} for ${ev.detail.seeme}`);
      const scrollTarget = document.querySelector(ev.detail.seeme);
      scrollToSection(scrollTarget);
    }
    // Listen for the custom event.
    targetEventElement.addEventListener("scrollToSomething", customEventHandler, false);
    
    //listen for the hash change; and dispatch event when it happens
    window.addEventListener('hashchange', function() {
      document.querySelector("body").dispatchEvent(customEventScroll);
    });
    //just here in case page does not have pattern?
    // THIS example test does not really use this.
    function checkURLMatch(pattern) {
      const currentUrl = window.location.href;
      // Check if the URL matches the common pattern
      const isCommonUrl = currentUrl.includes(pattern);
      if (isCommonUrl) {
        document.querySelector(attachTo)
          .dispatchEvent(customEventScroll);
      }
    }
    // dispatch the event on page load here JUST FOR THIS TEST
    checkURLMatch(targetEventElement.dataset.pattern);
    body {
      font-size: 16px;
      margin: 0;
      padding: 0;
    }
    
    .bigger-is-me {
      height: 100vh;
      border: solid 1px #FF0000;
      margin-bottom: 1em;
    }
    
    .fun-guy {
      margin-bottom: 5em;
    }
    <div class="bigger-is-me"> I just create some space to test</div>
    <div id="targetId" class="fun-guy">I am the target, could be the iframe</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search