即使弹出窗口被阻止,热键插件也会打开新窗口?

时间:2011-05-23 08:24:47

标签: javascript jquery jstree

如果按下“F2”,我想打开新窗口。下面的代码在firefox中给出了newWindow is null错误消息。如果我不使用弹出窗口阻止程序,它可以工作。在IE中也一样。即使使用弹出窗口阻止程序,它也可以在chrome中使用。

使用jstree pre 1.0 stable

            hotkeys: {
                "f3" : function () {
                url = "http://www.vse.cz";
                var newWindow = window.open(url, '_blank');
                newWindow.focus();
                return false;

            },

Q1:我可以让它适用于所有浏览器,以便用户在使用热键插件时无需更改设置吗?

Q2:为什么Using JavaScript instead of target to open new windows在Firefox中没有任何问题?那是因为它是一个链接,而不是使用热键插件?


我的理解是以某种方式从上面的脚本 操纵发生的事情 当用户点击链接时它改变了点击的属性 浏览器“不知道”它是新窗口,所以弹出窗口阻止程序是 绕过。

在我的情况下,我使用由其他东西触发的纯js函数,而不是 用户点击。并且'我的函数'不会更改任何html对象的属性。我认为这是不同的。我不确定我是不是 就在这里。

1 个答案:

答案 0 :(得分:7)

不幸的是,你无法在按键上打开一个新窗口(除了禁用弹出窗口阻止程序)。

IE,Firefox和Chrome中弹出窗口阻止程序的工作方式(从高级别开始)是由浏览器(在遇到调用window.open时)向上走动JavaScript调用堆栈以确定当前函数是 - 或由函数调用 - 是一个事件处理程序。换句话说,它会发现当前函数是否正在执行,因为用户做了触发DOM事件的事情。

如果是,则允许弹出窗口;否则它被阻止了。但是,哪些事件符合“弹出允许”的问题因浏览器而异。 By default in Mozilla,只有changeclickdblclickmouseupresetsubmit符合条件。 (我假设IE很相似。)

作为任何其他类型事件的事件处理程序的函数 - 例如您的keydown / keyup / keypress - 符合特殊条件弹出允许处理,这意味着您的弹出窗口被屏蔽,这就是您致window.open的回复null的原因。

然而,Chrome确实认为keydown事件有资格允许弹出窗口打开,这就是您的脚本在该浏览器中运行的原因。

Here's a reduced example来证明这是如何运作的。这个演示:

  • 定义名为spawn()的函数,该函数调用window.open以打开弹出窗口。
  • 在加载页面时立即调用spawn()。由于调用是从全局范围进行的,因此所有浏览器都会阻止此操作;它不是从事件处理程序调用的。
  • 将函数附加到调用window.onkeydown的{​​{1}}。如果您按Chrome中的任意键,弹出窗口将会打开,因为它允许来自spawn()处理程序的弹出窗口。在IE和Firefox中,弹出窗口将被阻止,因为那些浏览器不允许弹出键盘事件。
  • 将事件处理程序附加到调用keydown的链接。当您单击该链接时,将允许在所有浏览器中弹出窗口,因为对spawn()的调用可以追溯到window.open事件的事件处理程序。

正如您现在所看到的,没有任何东西可以操纵事件属性或“欺骗”浏览器而不知道有新窗口。允许通过链接点击打开弹出窗口的行为是按设计,理论上如果你点击某些东西,很可能你想要看到什么是在弹出窗口中。但是,当您从未执行任何操作的地方(例如全球范围)致电click时,您可能对任何[广告]感兴趣]在自动启动弹出窗口中。

通过这种方式,弹出窗口阻止程序可以防止烦恼(自动启动广告),同时仍允许页面根据用户的请求打开弹出窗口。