在一个iframe中的返回和前进按钮

35

如何使用JS在iframe中“实现”后退和前进按钮?

5个回答

48
使用window.history对象。
// For the current window
window.history.back();     
window.history.forward();

// For an iframe's window
iframe.contentWindow.history.back(); 
iframe.contentWindow.history.forward();

或者
iframe.contentWindow.history.go(-1); // back
iframe.contentWindow.history.go(1);  // forward

https://developer.mozilla.org/en/dom/window.history


@开发者:真的吗?在 Chrome 29.0.1521.3 dev 中这里运行良好,而且它在早期版本的 Chrome 中也可以运行。也许他们把它弄坏了,然后又修复了。 - Andy E
2
如果iframe被沙盒化了(即指向与包含页面不同的服务器),那么这个功能就无法使用。 - podperson
13
这里的棘手问题是,当你的iframe已经在自己的历史记录的开头时 - 并且脚本无法检测到这种情况 - 再次执行back()将会有效地触发包含页面上的back(),这几乎肯定不是你想要的结果。我迄今为止测试过的所有浏览器都是如此,包括Chrome 31.0.1650.57、Firefox 24和IE7等。 - mrec
1
@MikeC:是的,那是一个棘手的问题! - Andy E
3
你还可以使用一个监听器(或者一个不太美观的解决方案)来获取iframe中访问的所有URL,并将它们存储在一个数组中,然后手动实现一个返回和前进按钮,根据数组中定义的前/后项(如果有)更改iframe的SRC。 - Rayjax
4
谈论丑陋的问题,为了防止在iframe窗口的开始处按下返回按钮,您可以在iframe加载时添加一个变量“history=0”,以禁用返回按钮。前进历史记录+1,后退历史记录-1。 - Ricardo Gonçalves

13

2017年更新:如果iframe内容的源与包含页面的源不同,除非您控制远程源上的内容并可以使其接受postMessage事件,否则根本无法实现此操作。如果源相同,则旧答案仍然有效。

如果这是在您控制的应用程序中的WebView中,则还可以设置本地端点来控制此操作。


谢谢,我在尝试旧的解决方案并浪费时间之前就在寻找这种答案 :) - goamn

7

框架内的按钮:

<input type="button" value="Back" onclick="history.back()">

父框架内的按钮:

<input type="button" value="Back" onclick="frame_name.history.back()">

1

感谢大家提供宝贵的建议 :-) 我已经从你们的建议中开始,并进一步完善了它们。

我有一个网页,有两个垂直框架:左侧是一个窄列菜单栏(框架名称="menu"),右侧是一个主窗口(框架名称="main"),跨越大部分宽度。也就是说,index.htm 只包含整个表面的框架集。现在...为了解决简单框架集中的一般“返回”导航问题,我设法使用 Pavel Strakhov 建议的 input type=button - 只不过我必须进一步阐述 DOM 路径。由于我将按钮放在左侧的“menu”框架中,要导航的内容发生在右侧的“main”框架中,因此这两个框架是兄弟关系,而不是父子关系。因此,在我的情况下,我必须在层次结构中向上遍历一级,然后才能引用兄弟框架。结果,在我的情况下,按钮元素读取如下:

<input type="button" value="Back in the main frame" onclick="window.parent.main.history.back()">

或者您可以通过数组中的序数索引(从零开始)来引用框架,而不是按名称引用:

<input type="button" value="Back in the main frame" onclick="window.parent.frames[1].history.back()">

我还注意到,整个“onclick”属性可以附加到几乎任何其他可见元素上,例如锚点/ href(A),DIV或P。我也尝试过这些,使“返回”按钮看起来更像我的菜单的其余部分,但最终回到了粗糙的“按钮式”外观和行为,以使按钮更明显/突出/独特。它看起来很原始,但是效果最好。
实际上,在我的情况下,windows.parent实际上是指顶层框架-因此还有另一种方法来引用名为“main”的框架并告诉它返回:onclick="top.main.history.back()"。或者,显然,onclick="top.frames['main'].history.back()"
然后我发现,它仍然不可靠地工作。迄今为止发现的怪癖有:
  • 在Firefox v42左右,如果您返回并使用浏览器的“前进”按钮,几次URL点击之后可能会出现有趣的结果:有时框架中的history.back()函数会导致顶部框架上的history.back(),原因不明。

  • 在Firefox v42左右,有时浏览器自己的“后退”按钮会导致每个框架的history.back(),而不是顶部框架的history.back(),原因不明(=本地“后退”按钮的不一致行为)

  • 无论浏览器的制造和版本如何,某些网站显然会在站点加载时清除其基础框架的历史记录。如果在框架中加载这样的站点,则每个框架的history.back()将无效。

这可能是为什么很少有人再使用好老的HTML框架的另一个原因(除了同质化的样式)。结果的行为对用户来说不是非常确定/可预见/显而易见。这可能是为什么网站管理员更喜欢由表格或更现代的方法实现的固定列。或者也许只是因为现在每个人都使用CMS。


0

正如其他人所提到的,由于看似有缺陷的安全更改,这是一个重大问题。特别是,正如“mrec”在先前的评论中所说,这里的丑陋问题是,当您的iframe已经处于其自己的历史记录开头时 - 并且没有办法在脚本中检测到此条件 - 再次执行back()将有效地触发包含页面上的back(),这几乎肯定不是您想要的。 - 实际上,这对我来说是一个无法克服的问题。

这个解决方案是这里提到的响应的测试版本,其中历史记录是手动处理的,用户不能在历史记录开始之前遍历。它在http://www.0AV.com中用于内联帮助,并在此处进行了简化,这可能会对已经测试过的版本引入错误。它还可能需要一些调整以满足您的要求。

主机页面中的JS...

var Hstory = [], sorc = '';

window.onmessage = function(e){ //# message fired by iFrame with onmousedown="window.top.postMessage('...','*');" or etc.
    var hilitedCrefText = e.data;    
    switch(String(hilitedCrefText)){
        case "Help_Home": //# defined in iframe
            sorc = "/index.html"; //# eg
            HistryManager(sorc); //# store
            break;
        case "Help_Back": //# defined in iframe
            sorc = HistryManager(); //# retrieve
            break;
        default: //# anything else that is generated by a link.
            HistryManager(sorc);
    }    
    if( sorc.length > 0 ) document.getElementById('your_iframe_id').src = sorc;  
}


function HistryManager(toPush) { //# history_handler
    if (toPush != undefined) {
        Hstory.push(toPush);
    }else{
        if( Hstory.length > 1 ){
            var az = Hstory[Hstory.length-2]; //..
            //# -2 is: -1 as is base 1, + -1 as it just stored this location, so must go back to PRIOR locastion.
            Hstory = Hstory.slice(0, -1); // Reduce array (Use neg num to select from end of array)
            return az;
        }else{
            alert('End of history. \n\n(Can not go further Back).');
            return '';
        }
    }
} 

在 iframe 页面中使用 JS / HTML..

    <button onclick="window.top.postMessage('Help_Back','*');">Back</button>
    <button onclick="window.top.postMessage('Help_Home','*');">Home</button>

    <button onclick="window.top.postMessage('helppage1.html','*');">HelpOn1</button>
    <button onclick="window.top.postMessage('helppage2.html','*');">HelpOn2</button>

最后两个是用户可以遍历的链接示例(并添加到历史记录),在这种情况下作为按钮,但很容易更改为锚点。

希望这能帮助到某些人。(提示:我拼错了一些变量以防止与系统变量混淆)。代码是Codiad的附加内容,因此采用MIT许可证。


Ps:这适用于不同的域,但如果您无法控制iframes,则显然无法插入postMessage代码。在这种情况下,您可以将返回按钮等放在顶部(主机)页面中,但是然后您必须找出如何从iframe获取更改的URL(如果域与顶部页面不同,则可能不可能)。另一个注意事项-这不会禁用浏览器右键单击上下文菜单中的前进和后退条目。幸运的是,很少有人会使用它们。 - www-0av-Com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接