steven026 发表于 2022-6-8 15:34:16

如何通过脚本移除document右键事件

本帖最后由 steven026 于 2022-6-8 15:42 编辑

现有一个页面,通过document.addEventListener("contextmenu",fuc),绑定了一个鼠标右键事件,其中fuc是一个闭包内的函数。

我想用油猴或者脚本猫写一个脚本,每次进入这个页面时自动移除已经绑定的右键事件

百度查到了一个方法document.removeEventListener("contextmenu",getEventListeners(document).contextmenu.listener)
但是getEventListeners这个函数只能在Chrome Dev Tool里使用,油猴使用报错

我又想劫持document.addEventListener,结果发现油猴@grant环境中console.log(document.addEventListener)会发现不是native code,已经被劫持过了。

想求教大佬有什么办法解决吗?

李恒道 发表于 2022-6-8 16:28:51

run-at start+document.addEventListener劫持过滤绑定函数即可
[油猴脚本开发指南]addEventListener劫持
https://bbs.tampermonkey.net.cn/thread-967-1-1.html

cxxjackie 发表于 2022-6-8 21:32:57

https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=2110

steven026 发表于 2022-6-8 22:03:44

李恒道 发表于 2022-6-8 16:28
run-at start+document.addEventListener劫持过滤绑定函数即可
[油猴脚本开发指南]addEventListener劫持
ht ...

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @descriptiontry to take over the world!
// @author       You
// @include         *
// @run-at document-start
// @grant      unsafeWindow
// ==/UserScript==

(function() {
    'use strict';
    console.log(document.addEventListener) //这行导致下面劫持失效
    let oldadd=EventTarget.prototype.addEventListener
    EventTarget.prototype.addEventListener=function (...args){
      if(args=="contextmenu"){
            return false
      }
      oldadd.call(this,...args)
    }
})();
大佬想问一下,为什么多加了一行console.log(document.addEventListener)就导致劫持失效了
不加反而能生效?

steven026 发表于 2022-6-8 22:20:43

cxxjackie 发表于 2022-6-8 21:32
https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=2110

    document.addEventListener('contextmenu', function(e){
      console.log(123)
      e.stopImmediatePropagation()
    }, true);
谢谢,学到了,第一种方法对我也适用,之前试了e.stopPropagation()只能禁止向上对document没效果,没想到还有e.stopImmediatePropagation()能禁止同级

李恒道 发表于 2022-6-9 09:04:28

steven026 发表于 2022-6-8 22:03
大佬想问一下,为什么多加了一行console.log(document.addEventListener)就导致劫持失效了
不加反而能生 ...

呜呜呜
具体情况我也不知道
来个网址我调试看看?

steven026 发表于 2022-6-9 09:38:37

李恒道 发表于 2022-6-9 09:04
呜呜呜
具体情况我也不知道
来个网址我调试看看?

html:
<body>
<div id="div"></div>
<script>
    let div=document.getElementById("div")
    setTimeout(()=>{
      document.addEventListener("contextmenu",function(e){
            div.innerHTML+="<br>触发右键菜单事件"
            e.preventDefault();},false)
      div.innerHTML+="开始监听事件"
    },1000)
</script>
</body>

script:
// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @descriptiontry to take over the world!
// @author       You
// @include         *
// @run-at       document-start
// @grant      unsafeWindow
// ==/UserScript==

(function() {
    'use strict';
    console.log(document.addEventListener) //这行导致下面劫持失效
    let oldadd=EventTarget.prototype.addEventListener
    EventTarget.prototype.addEventListener=function (...args){
      console.log(...args)
      if(args=="contextmenu"){
            return false
      }
      oldadd.call(this,...args)
    }
})();
任何页面都这样,我随便写了个html你可以试试
console.log(document.addEventListener)不注释掉劫持就失败,注释掉劫持就成功

李恒道 发表于 2022-6-9 10:03:23

steven026 发表于 2022-6-9 09:38
html:




等我晚上研究一下
还真是
我草!

cxxjackie 发表于 2022-6-9 11:19:56

steven026 发表于 2022-6-9 09:38
html:




因为你在unsafeWindow + document-start的情况下读取了document,触发了油猴的一个神奇“特性”,在这篇文下面有过讨论:https://bbs.tampermonkey.net.cn/thread-1080-1-1.html
如果你想规避这个问题,可以在代码最前面加一句:
const document = unsafeWindow.document;

李恒道 发表于 2022-6-9 23:56:05

steven026 发表于 2022-6-9 09:38
html:




研究了一下
不一定对
油猴的执行机制是在with包裹了一个context
而context是一个proxy对象
当你访问document.queryselector
实际是访问了context(proxy对象window).document.addeventlister
而context.document返回的是一个get对象
再往后就没追了
总之一句话总结
doucment.addeventlister会触发油猴的包裹覆盖document函数
页: [1] 2
查看完整版本: 如何通过脚本移除document右键事件