可笑!在网页上复制点东西 还需要掏钱?教你copy事件的禁用

Jack_孟 / 2024-01-10 / 原文

前言

哈喽 大家好!

我是木易巷,我回来啦!!!

现在好多平台都变成了不开会员不能复制这样的情况。士可杀不可辱!作为一个优秀的复制粘贴工程师,在网页上复制点东西,还需要我掏钱?

今天木易巷给大家讲解一下怎样使用代码写出这种效果,并且分享给大家几个方法来实现破解,可以直接看视频哦~

 

 

 

正文

这里有一个非常简单的页面,是由一些文本构成的,我们在浏览器上打开,是肯定可以随意复制的,我们没有做一些处理,所以是没有什么问题的。

 

 

那么我们如何使用代码来实现禁用复制呢?

首先呢,我们需要去监听一个事件,叫做【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+事件名称直接绑定

该如何处理,先来一段代码:
  1. <body>
  2. <div class="copy-box">
  3. <p>text content</p>
  4. </div>
  5. </body>
上述代码中,得到一个这样的结构:body -> div.copy-box -> p。

我们分别在div.copy-box 、document、window上绑定一个click事件,如下:
  1. const ev = 'onclick'
  2. document.querySelector('.copy-box')[ev] = () => console.log('dom event: ' + ev)
  3. document[ev] = () => console.log('document event: ' + ev)
  4. window[ev] = () => console.log('window event: ' + ev)
根据js的事件冒泡机制,事件会从实际触发的节点依次向上冒泡。在上述代码里,window对象包含了整个网页的所有内容。document对象就是文档对象,包含了网页了所有节点信息,document也是window下的一个对象。根据包含关系得到以下结构:window -> document -> html ->body -> div.copy-box -> p。所以在上述代码执行时,会依次输出dom event: onclick、document event: onclick、window event: onclick。

敏锐一点,可以发现,事件的绑定都是在各自的最后出现[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] 即可,得到以下代码:
  1. const o = { value: null, writable: false }
  2. Object.defineProperty(HTMLElement.prototype, ev, o)
  3. Object.defineProperty(Document.prototype, ev, o)
  4. Object.defineProperty(window, ev, o)
让这段代码放在事件绑定之前运行,在页面再次点击div.copy-box,会发现绑定的事件不会在触发,达到了禁止的目的。

第二种事件绑定:使用addEventListener函数绑定。

  1. const ev = 'click'
  2. document.querySelector('.copy-box').addEventListener(ev, () => console.log('dom event: ' + ev))
  3. document.addEventListener(ev, () => console.log('document event: ' + ev))
  4. window.addEventListener(ev, () => console.log('window event: ' + ev))
我们发现,这时的事件绑定都使用了addEventListener函数,事件通过函数参数进行绑定,没有了之前的类似对象的键值关系,之前的禁止代码对于addEventListener失去了作用。但是,addEventListener是函数,那是不是可以提前篡改这个函数?
  1. HTMLElement.prototype._addEventListener = Element.prototype.addEventListener;
  2. Document.prototype._addEventListener = Document.prototype.addEventListener;
  3. Window.prototype._addEventListener = Window.prototype.addEventListener;
  4. HTMLElement.prototype.addEventListener = _xaddEventListener;
  5. Document.prototype.addEventListener = _xaddEventListener;
  6. Window.prototype.addEventListener = _xaddEventListener;
  7. function _xaddEventListener(a, b, c) {
  8. if (a != ev) this._addEventListener(a, b, c);
  9. };
这段代码中,我们在各自的原型链找到addEventListener,同时写一个自定义的_addEventListener函数,先将原本的addEventListener赋值给它。接着开始篡改原始addEventListener 。
函数,篡改的函数里对传入的事件进行判断,识别到click,直接丢弃不在处理。这是再次点击div.copy-box,会发现绑定的事件也不会在触发了,再次达到了禁止的目的。

第三种事件绑定:使用行内属性进行绑定。

  1. // html
  2. html -> onclick="clickfn('html')"
  3. body -> onclick="clickfn('body')"
  4. div -> onclick="clickfn('dom')"
上述代码中,我们在div、body、html处分别绑定了click事件。要达到事件失效,只需要干掉这个onclick属性即可。
  1. window.addEventListener('DOMContentLoaded', function() {
  2. const clicks = [...document.querySelectorAll('[' + onev + ']')]
  3. clicks.forEach(item => {
  4. item.removeAttribute(onev)
  5. item.removeAttribute(onev)
  6. })
  7. })
备注:DOMContentLoaded
MDN 的解释:当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。

上述代码里,我们将逻辑处理放到了事件DOMContentLoaded里运行,为了干掉所有的onclick属性,使用document.querySelectorAll来搜索。循环移除。
至此,事件的禁止就ok了。

贴上一份完整代码:
  1. const ev = 'copy'
  2. const onev = 'on' + ev
  3. const o = { value: null, writable: false }
  4. Object.defineProperty(HTMLElement.prototype, onev, o)
  5. Object.defineProperty(Document.prototype, onev, o)
  6. Object.defineProperty(window, onev, o)
  7. HTMLElement.prototype._addEventListener = Element.prototype.addEventListener;
  8. Document.prototype._addEventListener = Document.prototype.addEventListener;
  9. Window.prototype._addEventListener = Window.prototype.addEventListener;
  10. HTMLElement.prototype.addEventListener = _xaddEventListener;
  11. Document.prototype.addEventListener = _xaddEventListener;
  12. Window.prototype.addEventListener = _xaddEventListener;
  13. function _xaddEventListener(a, b, c) {
  14. if (a != ev) this._addEventListener(a, b, c);
  15. };
  16. window.addEventListener('DOMContentLoaded', function() {
  17. const clicks = [...document.querySelectorAll('[' + onev + ']')]
  18. clicks.forEach(item => {
  19. item.removeAttribute(onev)
  20. item.removeAttribute(onev)
  21. })
  22. })
这么让它在所有网页运行,**篡改猴** 你值得拥有。
  1. // ==UserScript==
  2. // @name 移除所有网页绑定的copy函数,实现自由复制
  3. // @version 1.0
  4. // @description try to take over the world!
  5. // @author -
  6. // @match *://*/*
  7. // @icon https://g.csdnimg.cn/static/logo/favicon32.ico
  8. // @grant none
  9. // @run-at document-start
  10. // ==/UserScript==
  11. (function() {
  12. 'use strict';
  13. // 上述完整代码放这
  14. })();

 

出处:https://www.duidaima.com/Group/Topic/jQuery/17823

=======================================================================================

个人使用

根据上面的思想,试了一下,发现并不行,还是无法复制,于是想到还是使用removeEventListener方法看看能否找到突破口,还真找到了,如下:

document.querySelector(".jbcode").removeEventListener("copy",getEventListeners(document.querySelector(".jbcode"))["copy"][0].listener)

需要的自行拿去。

=======================================================================================

如何查看html元素绑定的事件

在baidu中输入以上标题,baidu的AI自动生成的,如下:

要查看HTML元素绑定的事件,可以使用JavaScript来获取。

  1. 首先,需要通过选择器或者直接引用DOM对象来获取到目标HTML元素。比如,我们想要查看id为"myElement"的元素上绑定的事件,可以这样写:

var element = document.getElementById("myElement");
  1. 然后,可以使用getEventListeners()函数来获取该元素上所有已经注册的事件处理程序。示例如下:

var eventHandlers = getEventListeners(element);
console.log(eventHandlers); // 输出包含了该元素上所有事件及其相关信息的对象
  1. getEventListeners()返回的结果是一个对象,键名表示事件类型(比如click、mouseover等),值则是一个数组,每个元素都是一个事件处理程序的详细信息。

  2. 最后,根据自己的需求进行进一步操作,比如打印特定事件的处理程序、修改事件处理程序等。

希望能帮助到你!

提示:AI自动生成,仅供参考

 

 

 

出处:https://www.baidu.com/s?wd=%E5%A6%82%E4%BD%95%E6%9F%A5%E7%9C%8Bhtml%E5%85%83%E7%B4%A0%E7%BB%91%E5%AE%9A%E7%9A%84%E4%BA%8B%E4%BB%B6&rsv_spt=1&rsv_iqid=0xf86c0210000077e0&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&oq=%25E5%25A6%2582%25E4%25BD%2595%25E6%259F%25A5%25E7%259C%258Bhtml%25E5%2585%2583%25E7%25B4%25A0%25E7%259A%2584%25E4%25BA%258B%25E4%25BB%25B6&rsv_btype=t&inputT=3958&rsv_t=7708cz6ERTybRYJ0E3wYrpZhhrBX%2B2MrkeGmXDz37L0Ar8oo9IY3S2D%2B%2BPMiipoiM3pr&rsv_pq=bf22bdac000b6682&sug=%25E5%25A6%2582%25E4%25BD%2595&rsv_sug3=45&rsv_sug2=0&rsv_sug4=4872

=======================================================================================

JQuery事件机制

事件机制#

事件委托#

注册事件有以下几种方式:

  1. 简单事件绑定:$("div").click(function(){})
  2. bind事件绑定:$("div").bind("click mouseenter",function(){})
  3. delegate事件绑定
  4. on事件绑定(推荐)

delegate#

delegate:委托,给父元素注册委托事件,最终还是由子元素执行。

它有三个参数:
• 第一个参数:事件最终由谁来执行
• 第二个参数:事件类型
• 第三个参数:函数

Copy
<button>增加</button>
<div>
  <span>111</span>
  <p>1</p>
  <p>2</p>
</div>
Copy
$(function () {
  $("button").click(function () {
    $("<p>111</p>").appendTo("div")
  })

  // delegate:只能注册委托事件
  $("div").delegate("p", "click", function () {
    alert("eee")
  })
})

 

on#

它有四个参数:

  1. 第一个参数:绑定事件的名称;
  2. 第二个参数:执行事件的后代元素(可选),如果没有后代元素,那么事件将由自己执行;
  3. 第三个参数:传递给处理函数的数据,事件触发的时候通过 event.data 来使用(不常使用);
  4. 第四个参数:事件处理函数;

注册简单事件:

Copy
$("p").on("click", function () {
  alert("heh1")
})

注册委托事件:

Copy
$("div").on("click", "p", function () {
  alert("heh1")
})

 

事件解绑#

事件解绑有三种方式,分别是unbind、undelegate、off。

Copy
// unbind方式
$(selector).unbind()    // 解绑所有事件
$(selector).unbind("click")    // 解绑指定事件

// undelegate方式
$(selector).undelegate()    // 解绑所有undelegate事件
$(selector).undelegate("click")    // 解绑所有click事件

// off方式
$(selector).off()    // 解绑所有事件
$(selector).off("click")    // 解绑所有click事件

 

触发事件#

.trigger():根据绑定到匹配元素的给定的事件类型执行所有的处理程序和行为。

Copy
$(selector).click()    // 触发click事件
$(selector).trigger("click")