可笑!在网页上复制点东西 还需要掏钱?教你copy事件的禁用
前言
哈喽 大家好!
我是木易巷,我回来啦!!!
现在好多平台都变成了不开会员不能复制这样的情况。士可杀不可辱!作为一个优秀的复制粘贴工程师,在网页上复制点东西,还需要我掏钱?
今天木易巷给大家讲解一下怎样使用代码写出这种效果,并且分享给大家几个方法来实现破解,可以直接看视频哦~
正文
这里有一个非常简单的页面,是由一些文本构成的,我们在浏览器上打开,是肯定可以随意复制的,我们没有做一些处理,所以是没有什么问题的。
那么我们如何使用代码来实现禁用复制呢?
首先呢,我们需要去监听一个事件,叫做【copy】,当复制发生的时候,它就会触发这个事件的运行,而我们要做的其实就是禁用事件的默认行为。
不仅如此,我们好像还可以干点什么!
比如说当在进行复制的时候,给他复制一些其他的东西。我们修改代码,现在代码修改过后,复制在粘贴就会粘贴到我们设置的这一句:「创作不易,请点个赞再来复制!」
再比如说在进行复制的时候,给一个弹框提示。
现在我们修改代码,这个弹框提示呢,我们在复制这个行为发生的时候,自动提示:「若有问题,请联系木易巷!」
这样呢,我们就设置就完成了。
解决方法
好,我们知道了这个原理之后,再来回过头来看这个问题,怎样去破解这个禁用复制呢?
我们打开浏览器的调试控制台,然后找到事件监听器,将copy给移除掉就完事啦!
如果感觉这样去浏览器去找相关的代码,再删除掉,比较麻烦。那这里木易巷给大家推荐几个浏览器插件,大家通过浏览器扩展下载插件,然后就可以自动实现这种效果,不用在每一次就要去修改一下网页的源码啦!
插件名称:
1、网页万能复制
2、超级复制(Super Copy)
OK,本期的分享就到这里!
2024-01-10 11:15:25【出处】:https://zhuanlan.zhihu.com/p/622850658
=======================================================================================
如何让网页中的copy事件失效?
当我想在网页复制点内容,ctrl + c 时被要求告知需要加入vip,需要登陆,完了还得在我复制得内容后面随意拉屎。对于这样的流氓行为,我不想惯着它了,搞它。搞它前,先要知道,网页是怎么知道我复制内容了的?
js是运行在浏览器的唯一脚本语言,为了实现网页与用户的各种交互行为,实现了n多事件,最为常见的比如click点击事件。这些众多事件中,就有一个copy事件,用来监听用户的复制行为,比如执行ctrl + c 或是 右键复制。
现在知道了copy,那要阻止流氓行为,只要让网页中的copy事件失效就可以了。问题是,怎么才能让它失效?到这里,先搞清楚网页是如何绑定一个事件的?
一般来说绑定事件有 **三种常见形式**:
1.使用on+事件名称直接绑定
2.使用addEventListener函数绑定
3.使用行内属性进行绑定
第一种事件绑定:使用on+事件名称直接绑定
该如何处理,先来一段代码:- <body>
- <div class="copy-box">
- <p>text content</p>
- </div>
- </body>
我们分别在div.copy-box 、document、window上绑定一个click事件,如下:
- const ev = 'onclick'
- document.querySelector('.copy-box')[ev] = () => console.log('dom event: ' + ev)
- document[ev] = () => console.log('document event: ' + ev)
- window[ev] = () => console.log('window event: ' + ev)
敏锐一点,可以发现,事件的绑定都是在各自的最后出现[ev],ev是一个变量,值是:onclick。在不使用变量的情况下, 就是onclick。这就是js 对象数据类型的经典使用方式。
[ev] === .onclick. 这样完全可以把上述代码中的document.querySelector('.copy-box')、document、window看成对象结构,onclick就是这个对象中的某一个键,后面运行的函数就是值。既然是对象,那么是不是只要让这个对象的键onclick不被修改就可以了。是的, 想要锁定对象的值不能被修改,就得寄出 Object.defineProperty。defineProperty的基本语法:Object.defineProperty(对象, 键, {value[2], writable[3], enumerable[4]、configurable[5]})
要实现禁止对象的属性值被修改,只需关注writable[6] 即可,得到以下代码:
- const o = { value: null, writable: false }
- Object.defineProperty(HTMLElement.prototype, ev, o)
- Object.defineProperty(Document.prototype, ev, o)
- Object.defineProperty(window, ev, o)
第二种事件绑定:使用addEventListener函数绑定。
- const ev = 'click'
- document.querySelector('.copy-box').addEventListener(ev, () => console.log('dom event: ' + ev))
- document.addEventListener(ev, () => console.log('document event: ' + ev))
- window.addEventListener(ev, () => console.log('window event: ' + ev))
- HTMLElement.prototype._addEventListener = Element.prototype.addEventListener;
- Document.prototype._addEventListener = Document.prototype.addEventListener;
- Window.prototype._addEventListener = Window.prototype.addEventListener;
- HTMLElement.prototype.addEventListener = _xaddEventListener;
- Document.prototype.addEventListener = _xaddEventListener;
- Window.prototype.addEventListener = _xaddEventListener;
- function _xaddEventListener(a, b, c) {
- if (a != ev) this._addEventListener(a, b, c);
- };
函数,篡改的函数里对传入的事件进行判断,识别到click,直接丢弃不在处理。这是再次点击div.copy-box,会发现绑定的事件也不会在触发了,再次达到了禁止的目的。
第三种事件绑定:使用行内属性进行绑定。
- // html
- html -> onclick="clickfn('html')"
- body -> onclick="clickfn('body')"
- div -> onclick="clickfn('dom')"
- window.addEventListener('DOMContentLoaded', function() {
- const clicks = [...document.querySelectorAll('[' + onev + ']')]
- clicks.forEach(item => {
- item.removeAttribute(onev)
- item.removeAttribute(onev)
- })
- })
MDN 的解释:当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。
上述代码里,我们将逻辑处理放到了事件DOMContentLoaded里运行,为了干掉所有的onclick属性,使用document.querySelectorAll来搜索。循环移除。
至此,事件的禁止就ok了。
贴上一份完整代码:
- const ev = 'copy'
- const onev = 'on' + ev
- const o = { value: null, writable: false }
- Object.defineProperty(HTMLElement.prototype, onev, o)
- Object.defineProperty(Document.prototype, onev, o)
- Object.defineProperty(window, onev, o)
- HTMLElement.prototype._addEventListener = Element.prototype.addEventListener;
- Document.prototype._addEventListener = Document.prototype.addEventListener;
- Window.prototype._addEventListener = Window.prototype.addEventListener;
- HTMLElement.prototype.addEventListener = _xaddEventListener;
- Document.prototype.addEventListener = _xaddEventListener;
- Window.prototype.addEventListener = _xaddEventListener;
- function _xaddEventListener(a, b, c) {
- if (a != ev) this._addEventListener(a, b, c);
- };
- window.addEventListener('DOMContentLoaded', function() {
- const clicks = [...document.querySelectorAll('[' + onev + ']')]
- clicks.forEach(item => {
- item.removeAttribute(onev)
- item.removeAttribute(onev)
- })
- })
- // ==UserScript==
- // @name 移除所有网页绑定的copy函数,实现自由复制
- // @version 1.0
- // @description try to take over the world!
- // @author -
- // @match *://*/*
- // @icon https://g.csdnimg.cn/static/logo/favicon32.ico
- // @grant none
- // @run-at document-start
- // ==/UserScript==
- (function() {
- 'use strict';
- // 上述完整代码放这
- })();
出处:https://www.duidaima.com/Group/Topic/jQuery/17823
=======================================================================================
个人使用
根据上面的思想,试了一下,发现并不行,还是无法复制,于是想到还是使用removeEventListener方法看看能否找到突破口,还真找到了,如下:
document.querySelector(".jbcode").removeEventListener("copy",getEventListeners(document.querySelector(".jbcode"))["copy"][0].listener)
但是,对于使用addEventListener绑定的匿名函数,无法移除,还有就是getEventListeners只在控制台中有效,不是标准函数
不过看网上,还是给出了很多的方法,我自己进行修改了一下,如下:
// ==UserScript== // @name doCopy // @namespace http://tampermonkey.net/ // @version 0.2.3 // @description 解决csdn登录后才能复制、优化“关注阅读更多”功能、去除复制后的copyright小尾巴 // @author Jack // @match *blog.csdn.net/* // @match http*://*.csdn.net/* // @match http*://www.jb51.net/* // @grant none // @require https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js // @run-at document-end // ==/UserScript== (function (){ 'use strict'; doCopy(); // Your code here... $(document).ready(function(){ // 在此处执行希望在页面加载完成后执行的操作 //setTimeout(doCopy,1000); }); })(); function doCopy() { var host = window.location.host; //恢复csdn.net网站上代码的复制功能 if(host=="blog.csdn.net") { //优化登陆后复制 $('code').css({'user-select':'unset'}) $('#content_views').css({'user-select':'unset'}) $('#content_views pre').css({'user-select':'unset'}) //移除“登陆后复制”按钮 $('.hljs-button').remove(); //移除readmore按钮,并显示全文 $('#article_content').css({'height':'initial'}); $('.hide-article-box').remove(); //隐藏自动显示登录框 //$(".passport-login-container").css({'display':'none'}); $(".passport-login-container").remove(); //移除头部固定的作者信息 $(".column_info_box").remove(); //去除复制后的copyright小尾巴 document.querySelectorAll('*').forEach(item=>{ item.oncopy = function(e) { e.stopPropagation(); } }); } //恢复jb51.net网站上代码的复制功能 if(host=="www.jb51.net") { $('div .jb51code').css({'user-select':'unset'}); $("div .codetool").remove(); console.log("===========") window.addEventListener('copy', function(e){e.stopPropagation(); e.stopImmediatePropagation();}, true) //移除复制事件 $("div.jb51code").each((ind,ele) => { //var han=getEventListeners(ele); //var han2=ele.getEventListeners2(); //var l=han["copy"][0].listener; //debugger; //ele.removeEventListener("copy",getEventListeners(ele)["copy"][0].listener); //ele.removeEventListener("copy",function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}); //ele.unbind('copy'); //console.log(ele.getEventListeners(ele)) }); } //else { const ev = 'copy' const onev = 'on' + ev const o = { value: null, writable: false } Object.defineProperty(HTMLElement.prototype, onev, o) Object.defineProperty(Document.prototype, onev, o) Object.defineProperty(window, onev, o) HTMLElement.prototype._addEventListener = Element.prototype.addEventListener; Document.prototype._addEventListener = Document.prototype.addEventListener; Window.prototype._addEventListener = Window.prototype.addEventListener; HTMLElement.prototype.addEventListener = _xaddEventListener; Document.prototype.addEventListener = _xaddEventListener; Window.prototype.addEventListener = _xaddEventListener; function _xaddEventListener(a, b, c) { if (a != ev) this._addEventListener(a, b, c); }; window.addEventListener('DOMContentLoaded', function() { const clicks = [...document.querySelectorAll('[' + onev + ']')] clicks.forEach(item => { item.removeAttribute(onev) item.removeAttribute(onev) }) }) } }
// ==UserScript== // @name doCopy // @namespace http://tampermonkey.net/ // @version 0.2.3 // @description 解决csdn登录后才能复制、优化“关注阅读更多”功能、去除复制后的copyright小尾巴 // @author Jack // @match *blog.csdn.net/* // @match http*://*.csdn.net/* // @match http*://www.jb51.net/* // @grant none // @require https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js // @run-at document-end // ==/UserScript== (function (){ 'use strict'; doCopy(); // Your code here... $(document).ready(function(){ // 在此处执行希望在页面加载完成后执行的操作 //setTimeout(doCopy,1000); }); })(); function doCopy() { var host = window.location.host; //恢复csdn.net网站上代码的复制功能 if(host=="blog.csdn.net") { //优化登陆后复制 $('code').css({'user-select':'unset'}) $('#content_views').css({'user-select':'unset'}) $('#content_views pre').css({'user-select':'unset'}) //移除“登陆后复制”按钮 $('.hljs-button').remove(); //移除readmore按钮,并显示全文 $('#article_content').css({'height':'initial'}); $('.hide-article-box').remove(); //隐藏自动显示登录框 $(".passport-login-container").remove(); $(".passport-login-container").css({'display':'none'}); //移除登录提示框 $(".passport-login-tip-container false").remove(); $(".passport-login-tip-container false").css({'display':'none'}); //移除头部固定的作者信息 $(".column_info_box").remove(); //去除复制后的copyright小尾巴 document.querySelectorAll('*').forEach(item=>{ item.oncopy = function(e) { e.stopPropagation(); } }); console.log("=====[doCopy end : blog.csdn.net]=====") } //恢复jb51.net网站上代码的复制功能 if(host=="www.jb51.net") { $('div .jb51code').css({'user-select':'unset'}); $("div .codetool").remove(); window.addEventListener('copy', function(e){e.stopPropagation(); e.stopImmediatePropagation();}, true) //移除复制事件 $("div.jb51code").each((ind,ele) => { //var han=getEventListeners(ele); //var han2=ele.getEventListeners2(); //var l=han["copy"][0].listener; //debugger; //ele.removeEventListener("copy",getEventListeners(ele)["copy"][0].listener); //ele.removeEventListener("copy",function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}); //ele.unbind('copy'); //console.log(ele.getEventListeners(ele)) }); console.log("=====[doCopy end: www.jb51.net]=====") } //else { const ev = 'copy' const onev = 'on' + ev const o = { value: null, writable: false } Object.defineProperty(HTMLElement.prototype, onev, o) Object.defineProperty(Document.prototype, onev, o) Object.defineProperty(window, onev, o) HTMLElement.prototype._addEventListener = Element.prototype.addEventListener; Document.prototype._addEventListener = Document.prototype.addEventListener; Window.prototype._addEventListener = Window.prototype.addEventListener; HTMLElement.prototype.addEventListener = _xaddEventListener; Document.prototype.addEventListener = _xaddEventListener; Window.prototype.addEventListener = _xaddEventListener; function _xaddEventListener(a, b, c) { if (a != ev) this._addEventListener(a, b, c); }; window.addEventListener('DOMContentLoaded', function() { const clicks = [...document.querySelectorAll('[' + onev + ']')] clicks.forEach(item => { item.removeAttribute(onev) item.removeAttribute(onev) }) }) } }
v0.24:
// ==UserScript== // @name doCopy // @namespace http://tampermonkey.net/ // @version 0.2.4 // @description 解决csdn登录后才能复制、优化“关注阅读更多”功能、去除复制后的copyright小尾巴 // @author Jack // @match *blog.csdn.net/* // @match http*://*.csdn.net/* // @match http*://www.jb51.net/* // @grant none // @require https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js // @run-at document-end // ==/UserScript== (function (){ 'use strict'; doCopy(); // Your code here... $(document).ready(function(){ // 在此处执行希望在页面加载完成后执行的操作 //setTimeout(doCopy,1000); }); })(); function doCopy() { var host = window.location.host; //恢复csdn.net网站上代码的复制功能 if(host=="blog.csdn.net") { //优化登陆后复制 $('code').css({'user-select':'unset'}) $('#content_views').css({'user-select':'unset'}) $('#content_views pre').css({'user-select':'unset'}) //移除“登陆后复制”按钮 $('.hljs-button').remove(); //移除readmore按钮,并显示全文 $('#article_content').css({'height':'initial'}); $('.hide-article-box').remove(); $('main div.blog-content-box pre').css({'max-height':'none'}); //隐藏自动显示登录框 $(".passport-login-container").remove(); $(".passport-login-container").css({'display':'none'}); //移除登录提示框 $(".passport-login-tip-container false").remove(); $(".passport-login-tip-container false").css({'display':'none'}); //移除头部固定的作者信息 $(".column_info_box").remove(); //去除复制后的copyright小尾巴 document.querySelectorAll('*').forEach(item=>{ item.oncopy = function(e) { e.stopPropagation(); } }); console.log("=====[doCopy end : blog.csdn.net]=====") } //恢复jb51.net网站上代码的复制功能 if(host=="www.jb51.net") { $('div .jb51code').css({'user-select':'unset'}); $("div .codetool").remove(); window.addEventListener('copy', function(e){e.stopPropagation(); e.stopImmediatePropagation();}, true) //移除复制事件 $("div.jb51code").each((ind,ele) => { //var han=getEventListeners(ele); //var han2=ele.getEventListeners2(); //var l=han["copy"][0].listener; //debugger; //ele.removeEventListener("copy",getEventListeners(ele)["copy"][0].listener); //ele.removeEventListener("copy",function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}); //ele.unbind('copy'); //console.log(ele.getEventListeners(ele)) }); console.log("=====[doCopy end: www.jb51.net]=====") } //else { const ev = 'copy' const onev = 'on' + ev const o = { value: null, writable: false } Object.defineProperty(HTMLElement.prototype, onev, o) Object.defineProperty(Document.prototype, onev, o) Object.defineProperty(window, onev, o) HTMLElement.prototype._addEventListener = Element.prototype.addEventListener; Document.prototype._addEventListener = Document.prototype.addEventListener; Window.prototype._addEventListener = Window.prototype.addEventListener; HTMLElement.prototype.addEventListener = _xaddEventListener; Document.prototype.addEventListener = _xaddEventListener; Window.prototype.addEventListener = _xaddEventListener; function _xaddEventListener(a, b, c) { if (a != ev) this._addEventListener(a, b, c); }; window.addEventListener('DOMContentLoaded', function() { const clicks = [...document.querySelectorAll('[' + onev + ']')] clicks.forEach(item => { item.removeAttribute(onev) item.removeAttribute(onev) }) }) } }
v0.25:增加对blog.51cto.com的copy功能
// ==UserScript== // @name doCopy // @namespace http://tampermonkey.net/ // @version 0.2.5 // @description 解决csdn登录后才能复制、优化“关注阅读更多”功能、去除复制后的copyright小尾巴 // @author Jack // @match *blog.csdn.net/* // @match http*://*.csdn.net/* // @match http*://www.jb51.net/* // @match http*://blog.51cto.com/* // @grant none // @require https://cdn.bootcss.com/jquery/2.2.1/jquery.min.js // @run-at document-end // ==/UserScript== (function (){ 'use strict'; doCopy(); // Your code here... $(document).ready(function(){ // 在此处执行希望在页面加载完成后执行的操作 //setTimeout(doCopy,1000); }); })(); function doCopy() { var host = window.location.host; //恢复csdn.net网站上代码的复制功能 if(host=="blog.csdn.net") { //优化登陆后复制 $('code').css({'user-select':'unset'}) $('#content_views').css({'user-select':'unset'}) $('#content_views pre').css({'user-select':'unset'}) //移除“登陆后复制”按钮 $('.hljs-button').remove(); //移除readmore按钮,并显示全文 $('#article_content').css({'height':'initial'}); $('.hide-article-box').remove(); $('main div.blog-content-box pre').css({'max-height':'none'}); //隐藏自动显示登录框 $(".passport-login-container").remove(); $(".passport-login-container").css({'display':'none'}); //移除登录提示框 $(".passport-login-tip-container false").remove(); $(".passport-login-tip-container false").css({'display':'none'}); //移除头部固定的作者信息 $(".column_info_box").remove(); //去除复制后的copyright小尾巴 document.querySelectorAll('*').forEach(item=>{ item.oncopy = function(e) { e.stopPropagation(); } }); console.log("=====[doCopy end : blog.csdn.net]=====") } //恢复blog.51cto.com网站上代码的复制功能 if(host=="blog.51cto.com") { window.addEventListener('copy', function(e){e.stopPropagation();e.stopImmediatePropagation();}, true) window.addEventListener('keydown', function(e){e.stopPropagation();e.stopImmediatePropagation();}, true) window.addEventListener('keyup', function(e){e.stopPropagation();e.stopImmediatePropagation();}, true) console.log("=====[doCopy end: blog.51cto.com]=====") } //恢复jb51.net网站上代码的复制功能 if(host=="www.jb51.net") { $('div .jb51code').css({'user-select':'unset'}); $("div .codetool").remove(); window.addEventListener('copy', function(e){e.stopPropagation(); e.stopImmediatePropagation();}, true) //移除复制事件 $("div.jb51code").each((ind,ele) => { //var han=getEventListeners(ele); //var han2=ele.getEventListeners2(); //var l=han["copy"][0].listener; //debugger; //ele.removeEventListener("copy",getEventListeners(ele)["copy"][0].listener); //ele.removeEventListener("copy",function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}); //ele.unbind('copy'); //console.log(ele.getEventListeners(ele)) }); console.log("=====[doCopy end: www.jb51.net]=====") } //else { const ev = 'copy' const onev = 'on' + ev const o = { value: null, writable: false } Object.defineProperty(HTMLElement.prototype, onev, o) Object.defineProperty(Document.prototype, onev, o) Object.defineProperty(window, onev, o) HTMLElement.prototype._addEventListener = Element.prototype.addEventListener; Document.prototype._addEventListener = Document.prototype.addEventListener; Window.prototype._addEventListener = Window.prototype.addEventListener; HTMLElement.prototype.addEventListener = _xaddEventListener; Document.prototype.addEventListener = _xaddEventListener; Window.prototype.addEventListener = _xaddEventListener; function _xaddEventListener(a, b, c) { if (a != ev) this._addEventListener(a, b, c); }; window.addEventListener('DOMContentLoaded', function() { const clicks = [...document.querySelectorAll('[' + onev + ']')] clicks.forEach(item => { item.removeAttribute(onev) item.removeAttribute(onev) }) }) } }
需要的自行拿去。
=======================================================================================
如何查看html元素绑定的事件
在baidu中输入以上标题,baidu的AI自动生成的,如下:
要查看HTML元素绑定的事件,可以使用JavaScript来获取。
-
首先,需要通过选择器或者直接引用DOM对象来获取到目标HTML元素。比如,我们想要查看id为"myElement"的元素上绑定的事件,可以这样写:
-
然后,可以使用
getEventListeners()
函数来获取该元素上所有已经注册的事件处理程序。示例如下:
-
getEventListeners()
返回的结果是一个对象,键名表示事件类型(比如click、mouseover等),值则是一个数组,每个元素都是一个事件处理程序的详细信息。 -
最后,根据自己的需求进行进一步操作,比如打印特定事件的处理程序、修改事件处理程序等。
希望能帮助到你!
=======================================================================================
如何在 JS 文件中(非控制台)使用 getEventListeners 函数?
评论区
- “你不让我好过我也不让你过,都他妈的别过了”大法,干掉其他全局 API
比如,它这个页面的 copy
事件回调里用到了 window.getSelection()
来获取你选中的节点,那你就直接把这个 API 干掉,window.getSelection = null
。它的函数一执行就报错,自然不可能执行到修改剪切板内容的地方。当然,得确保这个不会影响页面的其他你所需要的功能,如果单单是个报错,就让他们的程序员看报错监控后苦思冥想吧。
你甚至可以覆盖原型链上的 addEventListener
不让 copy
事件绑定。
2. “谁起步早谁抢占制高点”大法,MutationObserver
比如页面里是给 .article-content
这个元素绑定的 copy
事件,那就想办法在它的 addEventListener()
执行前就就绑上自己的事件处理函数,在函数里执行 e.stopImmediatePropagation()
这样它自己的回调函数就不会触发了。具体难点就是怎么能比页面更快执行 addEventListener
,那就尝试用 MutationObserver
实时监听页面所增加的节点,不过由于它的回调也是异步触发的,所以这个方法也不一定能行。
3. “高级程序降维打击一般程序员”大法,事件捕获
一般程序员绑定事件都不加 addEventListener
的第三个参数,或者传 false
,这是事件冒泡阶段才触发的,你可以在事件传递更早的阶段,捕获阶段的第一个节点上,也就是 window 上绑定处理函数,不用管它是给具体哪个节点绑了 copy
,通杀:
window.addEventListener('copy', function(e){e.stopPropagation();e.stopImmediatePropagation();}, true)
你甚至可以在页面 load
事件后再执行这行代码 ,不慌不忙拿捏他。
js万物皆可覆盖,只要优先级够高。
只需要在html开头植入一段代码,确保它最先执行就可操控全局。例如
HTMLElement.protype.addEvenListener=function(){
}
这么做的话,全局的dom添加的事件都会失效(dom里的属性onxxxx=无效,它不是调用addEvenListrner添加的事件),因为所有元素都继承自HTMLElement,就像java所有对象都继承自java.lang.Object,根据这个特性,你就可以劫持所有后面添加的监听事件,就可以适当的不触发
考虑对addEventListener做劫持试试看?
let oldadd=EventTarget.prototype.addEventListener
EventTarget.prototype.addEventListener=function (...args){
console.log('addEventListener',...args)
oldadd.call(this,...args)
}
直接干掉ClipboardEvent.clipboardData的set不是更轻松么
出处:https://www.zhihu.com/question/520181485/answer/2379752368
这个文章让我看的,只能说评论区都是人才!!!
其实技术重要,但更重要的是想法!~
哈哈!~
=======================================================================================
js 获取元素绑定事件的列表 chrome getEventListeners、 Events-EventListenerList 、$._data(a[0], 'events').click[0].handler
技术上有什么办法获得指定 HTMLElement 上有绑定那些 #JavaScript 函数事件,及其处理函数么?
比如我有一个按钮,想知道他绑定了那些事件? click 事件的处理函数是什么?
elem.onclick
这种只能绑定唯一的一个事件处理函数,可以直接取到。
DOM Level 3 有 [http://www.w3.org/TR/2001/WD-DOM-Level-3-Events-20010823/events.html#Events-EventListenerList eventListenerList] 接口,但是现在还没有浏览器实现。
不过可以通过框架包装的方式获取列表。 另外 Google Chrome 浏览器的开发者工具有提供查看元素绑定了哪些事件的特性, 猜测是通过解析页面及其引入的 JavaScript 源码得到的 (据我所知,Firebug 的性能分析就是通过 inject 代码到各个函数中来实现的)。
延伸阅读
- http://www.w3.org/TR/2001/WD-DOM-Level-3-Events-20010823/events.html#Events-EventListenerList
- http://www.quirksmode.org/js/events_advanced.html
Chrome浏览器方法:getEventListeners
在控制台的listener中,只能显示函数的第一行,如果你写的函数是多行的,那就需要把命令打全了:
getEventListeners(document.getElementById("btn1")).click[0].listener
console会把函数的全部都打印出来。
jQuery读取事件列表的方法:
$(function(){
$("#atest1").click(function(e){
console.log("进入a链接跳转2");
location.href="http://www.baidu.com/?t="+new Date().getTime();
console.log("a链接跳转已经执行3");
});
setTimeout(function(){
document.addEventListener('click', function(e){
console.log("document事件捕获开始1");
// 通知浏览器不要执行与事件关联的默认动作。
// e.preventDefault();
console.log(e.toElement);
//控制台执行有效
//getEventListeners($("a#atest1").get(0)).click[0].remove();
// 显示当前目标元素的绑定事件有哪些
var a=$(e.toElement);
var p = $._data(a[0], 'events').click[0].handler;
if(p.toString().indexOf("location")>0){
$._data(a[0], 'events').click[0].handler=function(){}
}
$.get("http://www.raodaor.com/test/tag.ashx?stm=1464233065021", function(){
console.log("ajax");
if(p.toString().indexOf("location")>0){
$._data(a[0], 'events').click[0].handler=p();
}
});
}, true);
},1000);
});
出处:http://camnpr.com/javascript/2264.html
=======================================================================================
JQuery事件机制
事件机制#
事件委托#
注册事件有以下几种方式:
- 简单事件绑定:$("div").click(function(){})
- bind事件绑定:$("div").bind("click mouseenter",function(){})
- delegate事件绑定
- on事件绑定(推荐)
delegate#
delegate:委托,给父元素注册委托事件,最终还是由子元素执行。
它有三个参数:
• 第一个参数:事件最终由谁来执行
• 第二个参数:事件类型
• 第三个参数:函数
<button>增加</button>
<div>
<span>111</span>
<p>1</p>
<p>2</p>
</div>
$(function () {
$("button").click(function () {
$("<p>111</p>").appendTo("div")
})
// delegate:只能注册委托事件
$("div").delegate("p", "click", function () {
alert("eee")
})
})
on#
它有四个参数:
- 第一个参数:绑定事件的名称;
- 第二个参数:执行事件的后代元素(可选),如果没有后代元素,那么事件将由自己执行;
- 第三个参数:传递给处理函数的数据,事件触发的时候通过 event.data 来使用(不常使用);
- 第四个参数:事件处理函数;
注册简单事件:
$("p").on("click", function () {
alert("heh1")
})
注册委托事件:
$("div").on("click", "p", function () {
alert("heh1")
})
事件解绑#
事件解绑有三种方式,分别是unbind、undelegate、off。
// unbind方式
$(selector).unbind() // 解绑所有事件
$(selector).unbind("click") // 解绑指定事件
// undelegate方式
$(selector).undelegate() // 解绑所有undelegate事件
$(selector).undelegate("click") // 解绑所有click事件
// off方式
$(selector).off() // 解绑所有事件
$(selector).off("click") // 解绑所有click事件
触发事件#
.trigger():根据绑定到匹配元素的给定的事件类型执行所有的处理程序和行为。
$(selector).click() // 触发click事件
$(selector).trigger("click")
出处:https://www.cnblogs.com/mq0036/p/17956155#1170291741
js万物皆可覆盖,只要优先级够高。
只需要在html开头植入一段代码,确保它最先执行就可操控全局。例如
HTMLElement.protype.addEvenListener=function(){
}
这么做的话,全局的dom添加的事件都会失效(dom里的属性onxxxx=无效,它不是调用addEvenListrner添加的事件),因为所有元素都继承自HTMLElement,就像java所有对象都继承自java.lang.Object,根据这个特性,你就可以劫持所有后面添加的监听事件,就可以适当的不触发
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/17956125
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!