【问题标题】:hotkey plugin opens new window even if pop-ups are blocked?即使弹出窗口被阻止,热键插件也会打开新窗口?
【发布时间】:2011-05-30 13:04:53
【问题描述】:

如果按下“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 对象的属性。我认为这就是区别。我不确定我是不是 就在这里。

【问题讨论】:

    标签: javascript jquery jstree


    【解决方案1】:

    很遗憾,您无法通过按键打开新窗口(除了禁用弹出窗口拦截器)。

    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()。这被所有浏览器阻止,因为调用是从全局范围内进行的;它不是从事件处理程序中调用的。
    • 将函数附加到调用spawn()window.onkeydown。如果您在 Chrome 中按任意键,弹出窗口将打开,因为它允许来自 keydown 处理程序的弹出窗口。在 IE 和 Firefox 中,弹出窗口将被阻止,因为这些浏览器不允许来自键盘事件的弹出窗口。
    • 将事件处理程序附加到调用spawn() 的链接。当您单击该链接时,所有浏览器都将允许弹出窗口,因为对 window.open 的调用可以追溯到 click 事件的事件处理程序。

    正如您现在所看到的,没有任何事情继续操作事件属性或“欺骗”浏览器以不知道有一个新窗口。允许通过点击链接打开弹出窗口的行为是设计,其理论是,如果您点击了某物,您可能想要查看任何内容在弹出窗口中。但是,当从您没有做任何事情的地方(例如全局范围)向 window.open 拨打电话时,您可能对任何 [ad] 感兴趣在自动启动的弹出窗口中。

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

    【讨论】:

    • @josh:很好的解释,谢谢。 contextmenu jstree.com/documentation/contextmenu 函数被调用 / 是 triggered because of a mouse click 呢?我遇到与使用热键插件时相同的行为。
    • @Radek:contextmenu 事件——虽然逻辑上是鼠标点击——不在list of allowed events 上,所以没有骰子。 (还要考虑到contextmenu 不是必然因为鼠标点击而触发的——用户可以按下上下文菜单键或Shift+F10。)另外,你can't catch a right-click with a click handler(注意如果您左键或中键单击,数字会改变,但如果您右键单击则不会改变。)
    • 不确定我是否理解正确。那么,如果我使用鼠标左键单击,window.open 仍然无法工作?
    • @Radek:contextmenu 通常在右键单击时触发; click 作为左键或中键单击的结果触发。您可以从 click 事件打开弹出窗口,但不能从 contextmenu 事件打开。
    • native contextmenu DOM 事件仅在右键单击时触发。如果您正在谈论使用 jQuery 的事件处理程序触发机制 ($(element).trigger('contextmenu')),您需要意识到您实际上所做的是调用附加到事件的每个函数,但您不是 i> 导致本地 DOM 事件被触发。弹出规则基于调用函数的本机 DOM 事件应用,该函数又触发 jQuery 事件处理程序。这些规则根据被触发的 jQuery 事件应用。
    猜你喜欢
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    相关资源
    最近更新 更多