如何从点击事件中丢失可信上下文

时间:2019-01-14 00:08:04

标签: javascript google-chrome userscripts tampermonkey

我正在尝试创建一个用户脚本,以使本机弹出窗口阻止程序应用于所有弹出窗口,即使是那些由用户交互导致的弹出窗口。

我想到了以下想法:

window.addEventListener('click', function(e) {
  console.log(e.isTrusted);
  if (e.isTrusted) {
    e.stopImmediatePropagation();
    e.preventDefault();
    e.target.dispatchEvent(new e.constructor(e.type, e));
  }
}, true);

button.addEventListener('click', function(e) {
  window.open('about:blank');
});
<button id="button">Test</button>

(在代码段窗口中,由于iframe沙箱而无法打开。)

基本上,此想法是向页面添加事件侦听器,以将不可信的任何点击事件替换为不可信的副本。但是,这不起作用,弹出窗口仍处于打开状态。

有什么办法可以做到这一点?

此处的相关规范: https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-activation

2 个答案:

答案 0 :(得分:1)

这只是回答了这个 XY问题 X 部分,因为我认为 Y 没有真正的用途。

如果您希望阻止所有弹出窗口,那么Termination已经阻止了所有使用此方法制作的弹出窗口,那么您可能还希望阻止来自锚元素的弹出窗口,

window.open = null;

现在,您必须在所有文档中(也就是在iframe中)应用它,您应该会很好。

但是请注意,打开弹出窗口的页面有很多合法的原因,并且禁用它肯定会破坏很多网站。

答案 1 :(得分:0)

pop-blocker对事件上下文的处理似乎很复杂。即使生成带有评估字符串的setTimeout也不会破坏上下文。在Firefox中,单击后会出现一秒钟的时间来执行弹出窗口,后来认为它不会被单击触发。

但是,我可以让Firefox使用setInterval来阻止弹出窗口。我尚未在Chrome中进行测试。

我们用自定义的方法覆盖window.open方法:

      window.open = (function()
      {
        const
          openArgs  = [],
          fnOpen    = window.open.bind(window)
        ;

        setInterval( () => { for(let args; args = openArgs.pop(); fnOpen(args)); }, 100);

        return function open(...args) { openArgs.push(args); }  
      })();
<button onclick="window.open('http://example.com');">button</button>
<a href="javascript:window.open('http://www.example.com');">open</a>