【问题标题】:Updating an iframe, history and URL. Then making it work with back button更新 iframe、历史记录和 URL。然后使用后退按钮使其工作
【发布时间】:2015-07-03 17:45:53
【问题描述】:

点击浏览器上的后退按钮时,我在获取要更新的 URL 时遇到问题(我正在 Firefox 上进行测试)。更新 iframe 的“src”属性后,我使用replaceState 更新历史记录。如果我在此之后点击后退按钮,iframe 将返回上一页,但 URL 不会更新以反映这一点。

function updateURLBar(urlInfo) {
    var stateObj = { foo: "bar" };
    document.getElementById("iframeContent").src = urlInfo[1];
    window.history.replaceState(stateObj, "page 2", urlInfo[0]);
}

我是不是走错了路,还是我只是错过了一些东西。感谢您的任何帮助!

【问题讨论】:

  • 欢迎来到 SO。我不确定我是否理解,您是在尝试覆盖“后退”按钮的内置功能吗?或者您的页面上有后退按钮?
  • 两者都不是(我认为)。虽然如果覆盖后退按钮是要走的路,那么我全神贯注。如果我点击浏览器后退按钮,我只想更新 URL。目前,仅点击后退按钮只会显示上一页/iframe。 URL 不会改变以反映这一点。
  • 我在我的网站上创建了一个简单的测试页面来说明问题。我们是否允许发布指向个人网站的外部链接?抱歉,显然是 Stackoverflow 的新手。

标签: javascript html iframe browser-history


【解决方案1】:

您可能会发现 popstate 事件很有趣。

https://developer.mozilla.org/en-US/docs/Web/Events/popstate

首先,我将更改您拥有的几行代码...

function updateURLBar(urlInfo) {
    //we can get this stateObj later...
    var stateObj = { 
        foo: "bar",
        url: urlInfo[1]
    };

    //document.getElementById("iframeContent").src = urlInfo[1];

    // see EDIT notes
    changeIframeSrc(document.getElementById("ifameContent"), urlInfo[1]);

    //window.history.replaceState(stateObj, "page 2", urlInfo[0]);
    window.history.pushState(stateObj, "Page 2", urlInfo[0]);
}

然后你可以添加:

window.onpopstate = function(event) {
    //Remember our state object?
    changeIframeSrc( document.getElementById("iframeContent") ),event.state.url); // see EDIT notes.
};

编辑

Iframe 警告

使用 pushState 和更改 iframe src 属性时出现问题。如果 iframe 在 DOM 中,并且您更改了 src 属性,这将向浏览器历史堆栈添加一个状态。因此,如果您将history.pushStateiframe.src = url 一起使用,那么您将创建2 个历史条目。

解决方法

iframe 不在DOM 中时更改iframe 元素的src 属性将推送到浏览器历史堆栈。

因此,您可以构建一个新的iframe,将其设置为src 属性,然后将旧的iframe 替换为新的。

var changeIframeSrc = function(iframe, src) {
    var frame = iframe.cloneNode();
    frame.src = src;
    iframe.parentNode.replaceChild(frame, iframe);
};

【讨论】:

  • 谢谢诺曼。我之前实际上尝试过使用 pushState 并遇到了在历史记录中创建两个条目的相同实现。我也意识到 Chrome 和 Firefox 在这方面的表现也有所不同。我希望避免像你提到的解决方法,因为我对网站的开发还很远,但如果我找不到更好的解决方案,我可能不得不走这条路。谢谢!
  • 是的,当我发布我的原始答案时,我没有意识到 iframe 自己会这样做。我自己找不到更好的解决方案。祝你好运!
  • 由于我无法找到另一种解决方案,因此最终选择了这条路线。谢谢!
  • 让我建议另一种(可能更简洁)解决方法:使用 frame.contentWindow.location.replace(newUrl) 将 iframe 导航到新 url。这不会创建新的历史状态。
  • @tato 好建议!可能比cloneNode 策略更有效。
猜你喜欢
  • 1970-01-01
  • 2015-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多