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

Rad*_*dek 5 javascript jquery jstree

如果按下"F2",我想打开新窗口.下面的代码newWindow is null在firefox中给出了错误信息.如果我不使用弹出窗口阻止程序,它可以工作.在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;

            },
Run Code Online (Sandbox Code Playgroud)

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

Q2:为什么使用JavaScript代替目标打开新窗口在Firefox中没有任何麻烦?这是因为它是一个链接,而不是使用热键插件?


我的理解是,上面的脚本以某种方式操纵用户点击链接时会发生什么.它改变了点击的属性,因此浏览器"不知道"它是新窗口,因此绕过了弹出窗口阻止程序.

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

jos*_*736 7

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

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

如果是,则允许弹出窗口; 否则它被阻止了.但是,哪些事件符合"弹出允许"的问题因浏览器而异. 通过在Mozilla默认情况下,只有change,click,dblclick,mouseup,reset,和submit资格.(我假设IE很相似.)

这是任何其他类型的事件的事件处理功能-如keydown/ keyup/ keypress在你的情况-根本没有资格获得特殊的弹出窗口,允许处理,这意味着你的弹出窗口被阻止,这就是为什么您的来电window.open回报null.

但是,Chrome确实认为该keydown活动有资格允许弹出窗口打开,这就是您的脚本在该浏览器中运行的原因.

这是一个简化的例子来演示它是如何工作的.这个演示:

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

正如您现在所看到的,没有任何东西可以操纵事件属性或"欺骗"浏览器而不知道有新窗口.允许从链接点击打开弹出窗口的行为是设计理论,理论是如果你点击某些东西,很可能你看到弹出窗口中的内容.但是,当window.open您从未执行任何操作的地方(例如全局范围)进行呼叫时,您可能对自动启动弹出窗口中的[ad] 没有任何兴趣.

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