3

在自负类型开始之前的免责声明:这不是“在野外”部署的。这仅供 Chrome 插件在本地个人使用。我不是在试图欺骗我网站的访问者或做任何其他令人讨厌的事情。我已经看到了一些对那些想要在 onbeforeunload 上钩的人的批评。

一些背景

毫无疑问,我对 Chrome 的最大抱怨(至少在 Mac OS 上)是它的标签关闭按钮,当我打开多个标签时(就像我通常做的那样),由于标签本身变得相当小而且我经常无意中关闭标签因此标签关闭按钮未覆盖的点击目标区域非常小。在某些带有新闻故事、博客文章、文档等的标签上,这很烦人,但不是很大的不便。我只是 CMD+T 重新打开选项卡,并没有造成真正的伤害。但是,某些选项卡,尤其是 Gmail,在关闭时有明显的缺点。我经常与同事打开一个或多个聊天对话框并重新打开一个选项卡不会恢复聊天对话框,并且发起新的聊天会使我失去当前的聊天历史记录(是的,它已保存,但它 s 不能通过在上下文中向后滚动来方便地访问)。谷歌有一些要求添加选项以简单地删除标签关闭按钮(我自己更喜欢使用 CMD+W),但我并没有屏住呼吸。

部分解决方案

不久前,一位朋友向我介绍了dotJS Chrome 插件,它允许按域自定义 JavaScript 执行,类似于 GreaseMonkey,但略有不同。无论如何,它为我提供了一种在我经常访问的许多网站上“修复”问题/需求的方法,而且我发现它到目前为止非常有帮助。前几天我突然想到,我可以用一点 JavaScript 来打开我的 Gmail 等选项卡。我拼凑了一个基于正则表达式的小脚本,它会在关闭选项卡之前提示您。代码的要点如下:

var unloadHandler = function(e) {
    if (/(mail.google.com|google.com\/reader|gmail.com)/.test(location)) {
        return 'Are you sure you want to close: ' + location.host;
    }
};

window.onbeforeunload = unloadHandler;

瞧,这对我尝试过的大多数网站都起到了作用;除了一个:Gmail。让我纠正一下:它起作用了,因为它提示我确认关闭 Gmail 标签,如果我选择不关闭它,它会保持标签打开,但在对话框提示我之前,页面已经完全消失白色的。元素检查器显示标记仍然存在(据我所知),元素上的样式不应该隐藏东西(即显示:无;可见性:隐藏;等)并且元素的定位仍然正确(例如,它们在可视区域内)。我逐个删除元素以查看是否有任何东西遮挡了 Gmail 界面,但始终无法在屏幕上显示出来。我一生都无法弄清楚发生了什么。一世' 我不确定 Gmail 是否与我不知道的某些事件有关(on*before*beforeunload?),或者 Google 的浏览器是否对他们的 Gmail 页面做了一些特殊的事情,或者是什么导致了奇怪的行为。谷歌阅读器不受这种奇怪的影响(我可以防止关闭并保留页面的内容),就像我测试过的所有其他网站一样。

有谁知道可能导致此问题的原因?

作为记录,我正在运行以下命令:Mac OS X 10.6.5、Google Chrome 10.0.648.205 和 dotJS 1.3。

我感谢任何反馈,但我不是在寻找涉及以下内容的解决方案:固定选项卡、更改我的工作流程/使用情况(例如,不使用鼠标选择选项卡)等。我真的想弄清楚具体是什么,Gmail(或者可能是 Chrome ?) 这样做是在破坏我在这里的努力。提前致谢。

4

1 回答 1

2

我认为 Gmail 自己的代码会导致这种行为。我可以通过使用此功能从控制台订阅此事件来重现您的问题(在 linux 机器上)

window.onbeforeunload = function(e) {
    return "Hey what\'s wrong with you?!";
};

之后我启动了开发人员工具分析器,关闭窗口后的最后一次调用(并为问题选择“留在此页面上”的答案)是一个 removeChild 函数调用,它从 <iframe id=" 中删除了一些内容canvas_frame" />。所以内容元素不再存在。

function Fc(b) {
    return b && b.parentNode ? b.parentNode.removeChild(b) : m
}

我在订阅 beforeunload 事件的混淆代码中发现了一些“痕迹”,但很难确定 :)

function It(b, a) {
    this.Qc = jCa++;
    this.ea = b;
    this.ka = new J(this);
    this.Qa = a;
    this.Ka = [];
    this.Za = !1;
    this.ka.ya(this.ea, "unload", this.Da);
    this.ka.ya(this.ea, "beforeunload", this.ab);
    Ypa(Zd(a), this);
    this.ia()
}

我试图在 Firefox 中重现这种行为,但我认为谷歌为不同的浏览器提供了不同的 javascript 代码,所以我无法重现它。

于 2011-04-30T19:37:53.150 回答