【发布时间】:2016-06-14 00:15:56
【问题描述】:
我正在向我们的几个网站添加聊天功能。聊天会将用户与我们帮助台的人联系起来,以帮助他们使用网站。我们的帮助台人员希望聊天窗口看起来像页面侧面的标签并滑出,而不是在新窗口中弹出。但是,我想让用户在不丢失聊天记录的情况下浏览网站。
为此,我一直在尝试在聊天开始后将整个页面移动到 iframe 中(聊天在 iframe 之外),以便用户可以在 iframe 内浏览网站而不会丢失聊天。
我使用 this answer 开始使用,这在视觉上效果很好。但是,后台的一些 javascript 会中断。
其中一个站点是 ASP.NET Web 表单。另一个是MVC。我一直在使用网络表单。一旦页面被移动到 iframe 中,调用 __doPostBack 之类的东西就会中断,因为 javascript 上下文被抛在后面。
一旦用户点击一个链接(一个真正的链接,而不是 __doPostBack)并且 iframe 刷新,那么一切都会完美运行。
我怎么看,我有几个选择:
- 以某种方式将所有 javascript 变量从 window.top 复制到 iframe 中。希望不必知道所有变量名。我尝试了
this.contentWindow.__doPostBack = window.top.__doPostBack,它有效,但缺少其他变量,因此最终失败: - 以某种方式切换 iframe 的上下文以查看顶部窗口上下文,如果这可能的话?可能不会。
- 另一个想法是不要立即将页面移动到 iframe 中,而是等到页面更改后再将新页面加载到新的 iframe 中。但我不知道如何参与该事件并劫持它。
- 还有别的吗?
这些网站仅供我们员工使用,所以我只需要支持 IE11 和 Chrome。
更新:
感谢 LGSon 让我走上了使用目标属性的轨道(所以我可以使用方法 #3)。下面是我最终做的事情。当我弹出聊天时,我会拨打loadNextPageInIframe()。我在这里使用 jQuery,因为我们已经在我们的网站上使用了它,但是没有任何事情都可以完成。我在所有没有指向另一个框架或_blank的目标的链接上设置目标。我把 _parent 排除在外,但我认为我们无论如何都不会使用它。
我在一个名为“chatwindow”的全局变量中引用了我的聊天窗口 div。
在某些情况下这仍然可能不起作用,例如如果有一些 javascript 直接设置 window.location。如果我们的站点中有任何这样做的东西,我将不得不添加一种方法来处理它。
function loadNextPageInIframe() {
var frame = $("<iframe id=\"mainframe\" name=\"mainframe\" />").css({
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
border: "none",
display: "none"
}).appendTo("body");
$("form, a:not([target]), a[target=''], a[target='_top'], a[target='_self']").attr("target", "mainframe");
var firstload = true;
frame.load(function () {
//Runs every time a new page in the iframe loads
if (firstload) {
$(frame).show();
//Remove all elements from the top window except the iframe and chat window
$("body").children().not(frame).not(window.top.chatwindow).remove();
firstload = false;
}
//Make the browser URL and title reflect the iframe every time it loads a new page
if (this.contentWindow && this.contentWindow.location.href && window.top.location.hostname === this.contentWindow.location.hostname && window.top.location.href !== this.contentWindow.location.href) {
var title = this.contentDocument.title;
document.title = title;
if (window.top.history.replaceState) window.top.history.replaceState(null, title, this.contentWindow.location.href);
}
});
}
【问题讨论】:
标签: javascript asp.net iframe