【问题标题】:Back and forward buttons in an iframeiframe 中的后退和前进按钮
【发布时间】:2010-07-15 11:12:34
【问题描述】:

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

【问题讨论】:

    标签: javascript iframe


    【解决方案1】:

    使用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

    【讨论】:

    • 如果 iframe 被沙盒化(即指向与包含页面不同的服务器),那么这不起作用。
    • 这里的丑陋问题是,当您的 iframe 已经处于其自身历史的开始时 - 并且无法在脚本中检测到这种情况 - 执行另一个 back() 将有效地触发 back()而是在包含页面上,这几乎肯定不是您想要的。到目前为止,在我测试过的所有浏览器中都是如此。 Chrome 31.0.1650.57、Firefox 24、IE7...
    • @MikeC:是的,这是一个丑陋的问题!
    • 您还可以使用监听器(或更丑陋的解决方案)从 iframe 中获取所有访问过的 url,将它们存储在一个数组中,然后手动实现一个后退和前进按钮来更改 iframe SRC根据数组中的上一个/下一个项目(如果已定义)
    • 说说丑陋的,为了防止在iframe的窗口开始按下后退按钮,你可以在iframe加载时添加一个变量“history=0”并禁用后退按钮。前进历史+1,后退历史-1。
    【解决方案2】:

    2017 年更新:如果 iframe 内容的来源与封闭页面的来源不同,则无法执行此操作 - 除非您在远程来源控制内容并且可以让它接受 postMessage 事件.如果来源相同,则旧答案仍然有效。

    如果这是在您控制的应用程序中的 WebView 中,您还可以设置挂钩原生端来控制它。

    【讨论】:

    • 谢谢,在尝试旧的解决方案并浪费我的时间之前,我一直在寻找这种答案:)
    【解决方案3】:

    框架内的按钮:

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

    父框架内的按钮:

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

    【讨论】:

      【解决方案4】:

      感谢大家的宝贵指点 :-) 我已经设法从您的建议开始,并在它们的基础上进一步发展。

      我有一个有两个垂直框架的网页:左侧的窄列用于菜单栏(框架名称 =“菜单”),右侧的主窗口(框架名称 =“main”),跨越大部分的宽度。即,index.htm 只包含整个表面的框架集。现在......为了解决我的简单框架集中的一般“后退”导航问题,我设法使用 Pavel Strakhov 的 input type=button 建议 - 只是我必须进一步详细说明 DOM 路径。因为我在左侧的“菜单”框架中有按钮,并且要导航的内容发生在右侧的“主”框架中,所以这两个框架是同级的,而不是父级与子级。因此,就我而言,我必须在层次结构中向上遍历一个级别,然后才能引用同级框架。结果,在我的例子中,按钮元素读取

      &lt;input type="button" value="Back in the main frame" onclick="window.parent.main.history.back()"&gt;

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

      &lt;input type="button" value="Back in the main frame" onclick="window.parent.frames[1].history.back()"&gt;

      我还注意到,整个 'onclick' 属性几乎可以绑定到任何其他可见元素上,例如锚点/href (A)、DIV 或 P。我也尝试过这些,以使“后退”按钮看起来更像我的菜单的其余部分,但最终又回到了粗糙的“按钮式”外观和行为,使按钮更明显/突出/明显。它看起来很原始,但效果最好。

      实际上,在我的情况下,windows.parent 实际上是指顶部框架 - 所以还有另一种方式来引用我的框架,称为“main”并告诉它返回:onclick="top.main.history.back()"。或者,显然,onclick="top.frames['main'].history.back()"

      然后我发现,它仍然不能可靠地工作。目前发现的怪癖:

      • 在 v42 左右的 Firefox 中,如果您返回然后使用浏览器的“前进”按钮,接下来再点击几次 URL,您会得到有趣的结果:有时框架中的 history.back() 函数会无缘无故地在顶部框架上产生一个 history.back()。

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

      • 不管浏览器的品牌和版本如何,一些网站显然会在网站加载时清除其基本框架的历史记录。如果你在一个框架中加载这样的网站,每框架的 history.back() 什么都不做。

      这可能是几乎没有人再使用好的旧 HTML 框架的另一个原因(除了同质的样式)。由此产生的行为对用户来说不是非常确定/可预见/明显的。这可能就是为什么网站管理员更喜欢固定列,通过表格或更现代的方式实现。或者也许只是因为现在每个人都在使用 CMS。

      【讨论】:

        【解决方案5】:

        正如其他人所提到的,由于看似有缺陷的安全更改,这是当今的一个主要问题。特别是,正如“mrec”在之前的评论中所说,这里的丑陋问题是,当你的 iframe 已经处于它自己历史的开始时 - 并且无法在脚本中检测到这种情况 - 再做一次( ) 将有效地触发包含页面上的 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>
        

        ..last 2 是用户可以遍历(并添加到历史记录)的链接示例,在本例中为按钮,但很容易更改为锚点。

        希望对某人有所帮助。 (提示:我拼错了一些变量,以防止与系统变量混淆)。代码是 Codiad 的补充,因此是 MIT 许可证。

        【讨论】:

        • Ps:这适用于不同的域,但如果你不控制 iframe,显然你不能插入 postMessage 代码。在这种情况下,您可以将后退按钮等放在顶部(主机)页面中,但是您必须弄清楚如何从 iframe 获取更改的 URL(如果域与首页不同,这可能是不可能的)。另一个警告 - 这不会禁用浏览器右键单击下拉上下文菜单中的前进和后退条目。幸运的是,没有多少人会使用这些。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 1970-01-01
        相关资源
        最近更新 更多