我正在尝试在 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>