博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端复制问题
阅读量:6974 次
发布时间:2019-06-27

本文共 4780 字,大约阅读时间需要 15 分钟。

API介绍:

复制、剪切、粘贴事件:

copy 发生复制操作时触发;

cut 发生剪切操作时触发;
paste 发生粘贴操作时触发;
每个事件都有一个before事件对应:beforecopy、beforecut、beforepaste;

这几个before一般不怎么用,所以我们把注意力放在另外三个事件就可以了。

触发条件:

鼠标右键菜单的复制、粘贴、剪切;

使用了相应的键盘组合键,比如:command+c、command+v;

就算你是随便按的,也会触发事件。高程中介绍在Chorme、Firefox和Safari中,这几个before事件只会在真实会发生剪贴板事件的情况下触发,IE上则可以触发before。我实际测试的时候最新版chorme也会乱按也会触发,所以限制应该是在早一点的版本上。
so 想说的是:before这几个事件最好不要用,有关于剪切板的处理最好放在copy、cut、paste上面。

使用姿势:

以copy为例:
document.body.oncopy = e => {
// 监听全局复制 做点什么
}
// 还有这种写法:
document.addEventListener("copy", e => {
// 监听全局复制 做点什么
});
复制代码
上面是在document.body上全局监听的,然而很多人不知道的是,我们还可以为某些dom单独添加剪切板事件:
// html结构
<div id="test1"></div>
<div id="test2"></div>
// 写法一样:
let test1 = document.querySelector('#test1');
test1.oncopy = e => {
// 监听test1发生的复制事件 做点什么
// test1发生的复制事件会触发回调,其他地方不会触发回调
}
复制代码
其他事件也是一样的,这里就不赘述了。
clipboardData对象:用于访问以及修改剪贴板中的数据
兼容:
不同浏览器,所属的对象不同:在IE中这个对象是window对象的属性,在Chrome、Safari和Firefox中,这个对象是相应的event对象的属性。所以我们在使用的时候,需要做一下如下兼容:
document.body.oncopy = e => {
let clipboardData = (e.clipboardData || window.clipboardData);
// 获取clipboardData对象 + do something
}
复制代码
对象方法:
对象有三个方法: getData()、setData()、clearData()

getData() 访问剪切板中的数据

参数: getData()接受一个'text'参数,即要取得的数据的格式。
在复制、剪切、粘贴触发的事件的数据:
实际上在chorme上测试只有paste粘贴的时候才能用getData()访问到数据,用法如下:
要粘贴的数据:
document.body.onpaste = e => {
let clipboardData = (e.clipboardData || window.clipboardData); // 兼容处理
console.log('要粘贴的数据', clipboardData.getData('text'));
}
复制代码
被复制/剪切的数据:
在复制和剪切中的数据,需要通过window.getSelection(0).toString()来访问:
document.body.oncopy = e => {
console.log('被复制的数据:', window.getSelection(0).toString());
}
复制代码

setData(): 修改剪切板中的数据

参数:第一个参数也是'text',第二个参数是要放在剪切板中的文本。
剩下的留在下面仿知乎/掘金复制大段文本添加版权信息那里再说。

clearData() :

这个方法就不太知道了,试了好久不知道怎么用(如果有大佬知道,可以在评论区指点一下)。
如果只是为了禁止复制,或者禁止粘贴,在下面还有另外的方法可以做到,并且可以细粒化操作。

应用:

如果学习不是为了装X,那么一切将毫无意义,来看这个东西可以在哪些场景使用:
实现类知乎/掘金复制大段文本添加版权信息:
实现很简单:取消默认复制之后,主要是在被复制的内容后面添加信息,然后根据clipboardData的setData()方法将信息写入剪贴板。
可以直接复制这段代码到本地去试试。
// 掘金这里不是全局监听,应该只是监听文章的dom范围内。
document.body.oncopy = event => {
event.preventDefault(); // 取消默认的复制事件
let textFont, copyFont = window.getSelection(0).toString(); // 被复制的文字 等下插入
// 防知乎掘金 复制一两个字则不添加版权信息 超过一定长度的文字 就添加版权信息
if (copyFont.length > 10) {
textFont = copyFont + '\n'

  • '作者:OBKoro1\n'
  • '链接:'
  • '来源:掘金\n'
  • '著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。';
    } else {
    textFont = copyFont; // 没超过十个字 则采用被复制的内容。
    }
    if (event.clipboardData) {
    return event.clipboardData.setData('text', textFont); // 将信息写入粘贴板
    } else {
    // 兼容IE
    return window.clipboardData.setData("text", textFont);
    }
    }
    复制代码
    然后command+c、command+v,输出:
    你复制的内容
    作者:OBKoro1
    链接:
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    复制代码
    实现类起点网的防复制功能:

禁止复制+剪切

禁止右键,右键某些选项:全选,复制,粘贴等。
禁用文字选择,能选择却不能复制,体验很差。
user-select 用css禁止选择文本。

可以把代码拷到本地玩一玩:

// 禁止右键菜单
document.body.oncontextmenu = e => {
console.log(e, '右键');
return false;
// e.preventDefault();
};
// 禁止文字选择。
document.body.onselectstart = e => {
console.log(e, '文字选择');
return false;
// e.preventDefault();
};
// 禁止复制
document.body.oncopy = e => {
console.log(e, 'copy');
return false;
// e.preventDefault();
}
// 禁止剪切
document.body.oncut = e => {
console.log(e, 'cut');
return false;
// e.preventDefault();
};
// 禁止粘贴
document.body.onpaste = e => {
console.log(e, 'paste');
return false;
// e.preventDefault();
};
// css 禁止文本选择 这样不会触发js
body {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
复制代码
PS:

使用e.preventDefault()也可以禁用,但建议使用return false这样就不用去访问e和e的方法了。

示例中document.body全局都禁用了,也可以对dom(某些区域)进行禁用。

破解防复制:

上面的防复制方法通过js+css实现的,所以思路就是:禁用js+取消user-select样式。
Chrome浏览器的话:打开浏览器控制台,按F1进入Setting,勾选Disable JavaScript(禁止js)。

此时如果还不能复制的话,就要去找user-select样式,取消这个样式就可以了。

所以那些盗版小说手打的,我真的不太能理解,Excuse me???

点击复制功能:
不能使用clipboardData:
在IE中可以用window.clipboardData.setData('text','内容')实现。
上文提到过,在IE中clipboardData是window的属性。
而其他浏览器则是相应的event对象的属性,这实际上是一种安全措施,防止未经授权的访问,为了兼容其他浏览器,所以我们不能通过clipboardData来实现这种操作。
具体做法:

创建一个隐藏的input框

点击的时候,将要复制的内容放进input框中

选择文本内容input.select()

这里只能用input或者textarea才能选择文本。

document.execCommand("copy"),执行浏览器的复制命令。

function copyText() {
var text = document.getElementById("text").innerText; // 获取要复制的内容也可以传进来
var input = document.getElementById("input"); // 获取隐藏input的dom
input.value = text; // 修改文本框的内容
input.select(); // 选中文本
document.execCommand("copy"); // 执行浏览器复制命令
alert("复制成功");
}

dome---实例

<div class="wrapper">
<p id="text">我把你当兄弟你却想着复制我?</p>
<input id="input">
<button οnclick="copyText()">copy</button>
</div>

.wrapper {position: relative;}

#input {
position:absolute;
top:-10000px;
opacity: 0;
z-inde:-10;
}

function copyText() {  var text = document.getElementById("text").innerText;  var input = document.getElementById("input");  input.value = text; // 修改文本框的内容  input.select(); // 选中文本  document.execCommand("copy"); // 执行浏览器复制命令  alert("复制成功");}

转载于:https://blog.51cto.com/13507333/2157036

你可能感兴趣的文章
IIS编译器错误信息: CS0016:未能写入输出文件
查看>>
Python 的命令行参数处理 optparse->argparse
查看>>
label和input对齐的方法(转)
查看>>
【算法学习笔记】49.暴力穷举 BFS 剪枝 SJTU OJ 1357 相邻方案
查看>>
T51658 【wsy】签到题
查看>>
mysql 控制台上传数据库
查看>>
洛谷P1196 银河英雄传说
查看>>
aop为系统添加操作日志,注入或配置声明的方式来实现
查看>>
好用的日期控件jeDate
查看>>
Ajax学习之------>Ajax和Json实现无限下拉框联动(上)
查看>>
古今之成大事业、大学问者,必经过三种之境界
查看>>
我的Android进阶之旅------>Android中编解码学习笔记
查看>>
我的Android进阶之旅------>android如何将List请求参数列表转换为json格式
查看>>
转载:负载均衡器技术Nginx和F5的优缺点对比
查看>>
【资源共享】5G AP分析
查看>>
APP测试与Web测试的区别
查看>>
模式识别,计算机视觉领域,期刊
查看>>
AngularJs的UI组件ui-Bootstrap分享(三)——Accordion
查看>>
中缀、前缀和后缀表达式
查看>>
Redis 自定义对象 cannot be cast to java.lang.String
查看>>