我正在尝试创建一个用户脚本,以使本机弹出窗口阻止程序应用于所有弹出窗口,即使是那些由用户交互导致的弹出窗口。
我想到了以下想法:
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
答案 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>