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

huangapple go评论58阅读模式
英文:

Issue with scrolling to second section containing iframe on page reload

问题

Here is the translated code:

<script>
  // 定义要匹配的常见URL模式
  var commonUrlPatterns = [
    "/?step=index/step3",
    "/?step=index/step2/show"
    // 根据需要添加更多模式
  ];

  // 获取当前URL的函数
  function getCurrentURL() {
    return window.location.href;
  }

  // 存储初始URL
  var initialUrl = getCurrentURL();

  // 存储当前URL
  var currentUrl = initialUrl;

  // 检查URL变化的函数
  function checkURLChange() {
    // 获取先前的URL
    var previousUrl = currentUrl;

    // 获取当前的URL
    currentUrl = getCurrentURL();

    if (currentUrl !== previousUrl) {
      // 检查URL是否与任何常见模式匹配
      var matchedPattern = commonUrlPatterns.find(function (pattern) {
        return currentUrl.includes(pattern);
      });

      if (matchedPattern) {
        // 根据匹配的模式执行所需的操作
        scrollToSection("#iframe");
      }
    }
  }

  // 滚动到特定部分的函数
  function scrollToSection(targetSelector) {
    var targetElement = document.querySelector(targetSelector);
    if (targetElement) {
      targetElement.scrollIntoView({ behavior: "smooth" });
    }
  }

  // 检查初始URL是否与任何常见模式匹配
  var matchedInitialPattern = commonUrlPatterns.find(function (pattern) {
    return initialUrl.includes(pattern);
  });

  if (matchedInitialPattern) {
    // 根据匹配的模式执行所需的操作
    scrollToSection("#iframe");
  }

  // 定期检查URL变化
  setInterval(checkURLChange, 1000); // 根据需要调整间隔时间(以毫秒为单位)
</script>

If you have any further questions or need assistance with anything else, please let me know.

英文:

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(&quot;iframe&quot;);
var iframe = iframeContainer.querySelector(&quot;iframe&quot;);
var iframeSrc = iframe.getAttribute(&quot;src&quot;);
console.log(&quot;Page loaded&quot;);
// 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(&quot;Restored scroll position:&quot;, scrollPosition);
}
// Save the scroll position in the URL when the user scrolls
window.addEventListener(&quot;scroll&quot;, function() {
var scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
setScrollPositionToUrl(scrollPosition);
console.log(&quot;Saved scroll position:&quot;, scrollPosition);
});
// Modify the iframe code to remove scroll position from the URL on reload
iframe.addEventListener(&quot;load&quot;, function() {
removeScrollPositionFromUrl();
console.log(&quot;Iframe reloaded&quot;);
});
// 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 = &quot;#&quot; + 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(&quot;load&quot;, function() {
var iframeContainer = document.getElementById(&quot;iframe&quot;);
var iframe = iframeContainer.querySelector(&quot;iframe&quot;);
var commonUrlPattern = &quot;/?step=index/step3&quot;; // Update the common URL pattern as needed
console.log(&quot;Page loaded&quot;);
// Check if the URL contains the common pattern and the iframe has loaded
if (window.location.href.includes(commonUrlPattern)) {
console.log(&quot;Common URL pattern found&quot;);
scrollToSection();
}
// Function to scroll to the custom section
function scrollToSection() {
// Replace &#39;section-id&#39; with the actual ID of the section you want to scroll to
var sectionId = &quot;section-id&quot;;
var sectionElement = document.getElementById(sectionId);
if (sectionElement) {
sectionElement.scrollIntoView({ behavior: &quot;smooth&quot; });
}
}
// Listen for iframe load event to track URL changes within the iframe
iframe.addEventListener(&quot;load&quot;, function() {
console.log(&quot;Iframe loaded&quot;);
var iframeUrl = iframe.contentWindow.location.href;
if (iframeUrl.includes(commonUrlPattern)) {
console.log(&quot;Common URL pattern found within iframe&quot;);
scrollToSection();
}
});
});

@Mark Schultheiss has provided the suggestions, based on it this code works:

&lt;script&gt;
// Define the common URL patterns to match against
var commonUrlPatterns = [
&quot;/?step=index/step3&quot;,
&quot;/?step=index/step2/show&quot;
// 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(&quot;#iframe&quot;);            
}
}
}
// Function to scroll to a specific section
function scrollToSection(targetSelector) {
var targetElement = document.querySelector(targetSelector);
if (targetElement) {
targetElement.scrollIntoView({ behavior: &quot;smooth&quot; });
}
}
// 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(&quot;#iframe&quot;);     
}
// Periodically check for URL changes
setInterval(checkURLChange, 1000); // Adjust the interval as needed (in milliseconds)
&lt;/script&gt;

答案1

得分: 1

以下是翻译好的内容:

现代方式是创建自定义事件,然后根据需要触发它。

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

我还创建了一个“test”来触发它,以作为此示例的片段,以查看仅限于此示例的滚动效果。

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

参考链接: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'; //可以是任何元素
const targetEventElement = document.querySelector(attachTo);
targetEventElement.dataset.scrollTarget = "#targetId";
targetEventElement.dataset.pattern = "/?step=index/step3";

// 仅用于此示例!
const testThisExample = "https://stacksnippets.net/js";
targetEventElement.dataset.pattern = testThisExample;

// 所以我们可以在事件处理程序中看到这个
const details = {
  pattern: targetEventElement.dataset.pattern,
  seeme: targetEventElement.dataset.scrollTarget
};

// 使用上面的详情创建自定义事件
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);
}

// 监听自定义事件。
targetEventElement.addEventListener("scrollToSomething", customEventHandler, false);

// 监听哈希更改,并在发生时触发事件
window.addEventListener('hashchange', function() {
  document.querySelector("body").dispatchEvent(customEventScroll);
});
// 以防万一页面没有模式?
// 仅供此测试使用的此示例不会真正使用它。
function checkURLMatch(pattern) {
  const currentUrl = window.location.href;
  // 检查URL是否与常见模式匹配
  const isCommonUrl = currentUrl.includes(pattern);
  if (isCommonUrl) {
    document.querySelector(attachTo)
      .dispatchEvent(customEventScroll);
  }
}
// 在此处调度事件,仅供此测试使用
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">我只是创建一些空间来测试</div>
<div id="targetId" class="fun-guy">我是目标,可以是 iframe</div>
英文:

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

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const attachTo = &#39;.bigger-is-me&#39;;//could be any element
const targetEventElement = document.querySelector(attachTo);
targetEventElement.dataset.scrollTarget = &quot;#targetId&quot;;
targetEventElement.dataset.pattern = &quot;/?step=index/step3&quot;;
// just for this example here!
const testThisExample = &quot;https://stacksnippets.net/js&quot;
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(&quot;scrollToSomething&quot;, {
detail: details
});
function scrollToSection(targetElement) {
targetElement.scrollIntoView({
behavior: &quot;smooth&quot;
});
}
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(&quot;scrollToSomething&quot;, customEventHandler, false);
//listen for the hash change; and dispatch event when it happens
window.addEventListener(&#39;hashchange&#39;, function() {
document.querySelector(&quot;body&quot;).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);

<!-- language: lang-css -->

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

<!-- language: lang-html -->

&lt;div class=&quot;bigger-is-me&quot;&gt; I just create some space to test&lt;/div&gt;
&lt;div id=&quot;targetId&quot; class=&quot;fun-guy&quot;&gt;I am the target, could be the iframe&lt;/div&gt;

<!-- end snippet -->

答案2

得分: 0

我使用了这段代码,它似乎可以工作,但如果有人能提出改进的代码,我将不胜感激:

  // 定义要匹配的常见URL模式
  var commonUrlPattern = "/?step=index/step3";

  // 获取当前URL的函数
  function getCurrentURL() {
    return window.location.href;
  }

  // 存储初始URL
  var initialUrl = getCurrentURL();

  // 存储当前URL
  var currentUrl = initialUrl;

  // 检查URL更改的函数
  function checkURLChange() {
    // 获取前一个URL
    var previousUrl = currentUrl;

    // 获取当前URL
    currentUrl = getCurrentURL();

    if (currentUrl !== previousUrl) {
      // 检查URL是否匹配常见模式
      var isCommonUrl = currentUrl.includes(commonUrlPattern);

      if (isCommonUrl) {
        // 执行所需的操作或功能
        // 例如,滚动到特定部分
        scrollToSection();
      } else {
        // URL不匹配常见模式的处理
      }
    }
  }

  // 滚动到特定部分的函数
  function scrollToSection() {
    // 在此处编写滚动到所需部分的代码
    // 例如:
    var targetElement = document.getElementById("iframe");
    if (targetElement) {
      targetElement.scrollIntoView({ behavior: "smooth" });
    }
  }

  // 检查初始URL是否匹配常见模式
  var isInitialUrlCommon = initialUrl.includes(commonUrlPattern);
  if (isInitialUrlCommon) {
    // 执行所需的操作或功能
    // 例如,滚动到特定部分
    scrollToSection();
  } else {
    // 初始URL不匹配常见模式的处理
  }

  // 定期检查URL更改
  setInterval(checkURLChange, 1000); // 根据需要调整间隔(以毫秒为单位)

这是您提供的代码的翻译部分。

英文:

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 = &quot;/?step=index/step3&quot;;
// 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(&quot;URL changed:\nPrevious URL: &quot; + previousUrl + &quot;\nCurrent URL: &quot; + currentUrl);
// Check if the URL matches the common pattern
var isCommonUrl = currentUrl.includes(commonUrlPattern);
if (isCommonUrl) {
// alert(&quot;Common URL pattern found&quot;);
// Perform the desired action or function here
// For example, scroll to a specific section
scrollToSection();
} else {
// alert(&quot;Common URL pattern not found&quot;);
}
}
}
// 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(&quot;iframe&quot;);
if (targetElement) {
targetElement.scrollIntoView({ behavior: &quot;smooth&quot; });
}
}
// Check if the initial URL matches the common pattern
var isInitialUrlCommon = initialUrl.includes(commonUrlPattern);
if (isInitialUrlCommon) {
// alert(&quot;Common URL pattern found initially&quot;);
// Perform the desired action or function here
// For example, scroll to a specific section
scrollToSection();
} else {
// alert(&quot;Common URL pattern not found initially&quot;);
}
// Periodically check for URL changes
setInterval(checkURLChange, 1000); // Adjust the interval as needed (in milliseconds)

huangapple
  • 本文由 发表于 2023年5月31日 22:40:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76374698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定