2

我正在尝试在 iframe 模式下使用 FancyBox 2 来实现模态编辑对话框。关闭带有编辑表单的 iframe 后,我希望能够运行特定代码以在父窗口中执行操作,例如重新加载内容。由于服务器端验证,iframe 中的表单使用常规表单帖子,而不是 ajax,并且可以进行多次提交。

为了在对话框关闭后在主页中执行我的代码,我填充了 FancyBox afterClose 属性。

问题: 如果我在成功提交/验证表单数据后简单地关闭 iframe,则 iframe 会关闭,并且 afterClose 代码会按预期正确执行。问题是到那时窗口历史记录会被其他条目破坏。这意味着,一旦 iframe 关闭,我需要多次单击后退按钮(等于 iframe 中提交的数量)才能返回到托管 iframe 之前的页面。

为了解决这个问题,我尝试跟踪 iframe 中的历史深度并执行 window.history.go(-depth),然后再执行 parent.$.fancybox.close() 以关闭 iframe。这会处理历史问题,但会阻止执行 afterClose 代码。一些实验表明,在历史上返回原始 iframe 页面会以阻止 afterClose 运行的方式杀死 FancyBox(甚至不执行 parent.$.fancybox.close())。

问题: 有人知道为什么 FancyBox iframe 在按下后退按钮的次数足够多以到达 iframe 中加载的原始页面时会被破坏吗?这可以防止吗?当 FancyBox iFrame 关闭时,是否有不同的方法可以倒回 iFrame 历史记录?

示例:此页面 说明了问题。相同的来源如下:

FancyBoxMain.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Main</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
    <link rel="stylesheet" href="http://fancyapps.com/fancybox/source/jquery.fancybox.css" type="text/css" media="screen" />
    <script type="text/javascript" src="http://fancyapps.com/fancybox/source/jquery.fancybox.pack.js"></script>
    <script type="text/javascript">
        function popup() {
            var options = {
                type: 'iframe',
                href: 'FancyBoxPopup.html',
                height: 250,
                modal: true,
                autoSize: false,
                afterClose: function () { alert('Executing afterClose.'); }
            };
            $.fancybox.open(options);
        };
    </script>
</head>
<body>
    <input type="button" onclick="popup();" value="Popup"/>
</body>
</html>

FancyBoxPopup.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Popup</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript">
        var url;
        var depth;

        $(function() {
            var pos = window.location.href.indexOf('?');
            depth = pos == -1 ? 0 : parseInt(window.location.href.substr(pos + 1));
            $('#depth').text(depth);
            url = pos == -1 ? window.location.href : window.location.href.substr(0, pos);
            if (depth > 0) {
                $('#actions').show();
            }
        });
    </script>
</head>
    <body style="padding: 0; margin: 0;">
        <div>
            Depth:
            <span id="depth"></span>
            <input type="button" value="Add" onclick="window.location.href = '?' + (depth + 1).toString();" />
        </div>
        <div id="actions" style=" display: none;padding: 0; margin: 0;">
            <input type="button" value="Close FancyBox" onclick="parent.$.fancybox.close();"/>
            <input type="button" value="Rewind History, before closing FancyBox" onclick="history.go(-depth); parent.$.fancybox.close();"/>
            <input type="button" value="Back" onclick="window.history.back();" />
            <div>Bad behavior:
                <ul>
                    <li>Simply closing FancyBox allows the afterClose handler to run. The problem is that when depth > 0, the iFrame's history is kept, breaking correct functionality of the browser's back button.</li>
                    <li>Rewinding history back to 0 depth kills FancyBox, preventing the afterClose handler from firing. You can see this step-by-step by clicking the back button.</li>
                </ul>
            </div>
        </div>
    </body>
</html>
4

0 回答 0