在页面重新加载时滚动到包含 iframe 的第二部分时出现问题

Issue with scrolling to second section containing iframe on page reload

提问人:Kuzma 提问时间:5/31/2023 最后编辑:Kuzma 更新时间:6/2/2023 访问量:60

问:

我有一个网站,我使用的是第三方公司的 iframe。iframe 放置在 ID 为“iframe”的 div 中。我面临的问题是,当用户单击它中的任何按钮时,它会重新加载我的整个页面,滚动位置会重置为顶部。因此,用户需要再次向下滚动才能看到更新的内容,这并不理想。此外,用户甚至不会怀疑发生了什么事,因为 iframe 被放置在网站的第二部分。iframe

我尝试使用 JavaScript 在完成加载后滚动到包含 iframe 的第二部分。但是,到目前为止,我还没有成功。

我不确定这是否是正确的方法。我尝试使用此代码(它是由其他人提供的)。但是在重新加载 iFrame 后,新位置设置为“0”:

    Saved scroll position: 0
    Iframe reloaded

可能代码必须仅在 中舔一舔时触发,链接在开始时有一些共同的模式iFrame

这是我当前使用的代码:

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);
  }
};


我将不胜感激有关如何解决此问题的任何帮助。如何确保页面在完成加载后自动滚动到包含 iframe 的第二部分?提前感谢您的帮助!

更新

我简化了方法:尝试检查 URL 是否包含通用模式,然后相应地操作滚动位置(使用哈希链接)。但是,此方法并不一致,并且在重新加载页面后无法正确恢复滚动位置。

重要的是,我发现当单击iframe中的链接时,主页不会完全重新加载。因此,在 iFrame 重新加载后,主页的 URL 会更新为新地址,并且滚动将我带到顶部。因此,当 URL 更改时,我实现的代码没有机会执行。

这是我尝试过的:

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();
    }
  });
});

@Mark Schultheiss 提供了建议,但基于它,此代码可以工作:

<script>
  // Define the common URL patterns to match against
  var commonUrlPatterns = [
    "/?step=index/step3",
    "/?step=index/step2/show"
    // Add more patterns as needed
  ];

  // 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) {
      // Check if the URL matches any of the common patterns
      var matchedPattern = commonUrlPatterns.find(function (pattern) {
        return currentUrl.includes(pattern);
      });

      if (matchedPattern) {
        // Perform the desired action based on the matched pattern
                  
            scrollToSection("#iframe");            
        
      }
    }
  }

  // Function to scroll to a specific section
  function scrollToSection(targetSelector) {
    var targetElement = document.querySelector(targetSelector);
    if (targetElement) {
      targetElement.scrollIntoView({ behavior: "smooth" });
    }
  }

  // Check if the initial URL matches any of the common patterns
  var matchedInitialPattern = commonUrlPatterns.find(function (pattern) {
    return initialUrl.includes(pattern);
  });

  if (matchedInitialPattern) {
    // Perform the desired action based on the matched pattern
         
        scrollToSection("#iframe");     
    
  }

  // Periodically check for URL changes
  setInterval(checkURLChange, 1000); // Adjust the interval as needed (in milliseconds)
</script>

JavaScript HTML jQuery iframe

评论

0赞 Mark Schultheiss 5/31/2023
使用 表示可能需要更清楚地了解相关事件。setTimeout(function() {
0赞 Kuzma 5/31/2023
您能详细说明一下@MarkSchultheiss吗?
0赞 Mark Schultheiss 5/31/2023
相关 javascript.info/onload-ondomcontentloaded#
0赞 Kuzma 6/1/2023
你的意思是这样的:我已经把它粘贴到网站的最底部,但这不起作用document.addEventListener("DOMContentLoaded", function() { var iframeContainer = document.getElementById("iframe"); var iframe = iframeContainer.querySelector("iframe"); var iframeSrc = iframe.getAttribute("src"); iframe.addEventListener("load", function() { window.scrollTo(0, iframeContainer.offsetTop); }); });
0赞 Mark Schultheiss 6/1/2023
会着火吗?还是在添加侦听器之前就已经触发了?如果将其从包装器事件处理程序中取出会怎样? 等放置在包含页面底部?甚至或 - 免责声明 - 这只是一个超快的评论,几乎没有(任何)时间来考虑它 - 某些浏览器可能不会触发它。iframe.addEventListener("load"document.querySelector("iframe").addEventListener("load"document..querySelector("iframe").onLoad = document.getElementById('iframe').contentWindow.onload = myhandler;

答:

0赞 Kuzma 6/1/2023 #1

我已经使用了这段代码,它似乎有效,但如果有人可以建议改进的代码,我将不胜感激:


  // 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)


1赞 Mark Schultheiss 6/1/2023 #2

现代方法是创建一个自定义事件,然后根据需要触发该事件。

在这里,我设置了哈希更改事件处理程序来执行此操作(在此代码片段中未触发)

我还创建了一个“测试”,在这里将其作为片段触发,以仅查看此示例的滚动效果。

这有点人为,但我认为你可以从中构建。

参考: https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events 哈希更改 参考: 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>

评论

0赞 Kuzma 6/2/2023
谢谢,我已经根据我的需要更新了您的代码,并且可以正常工作。我已经更新了我的第一个线程