

前端js常用剪贴板(复制粘贴)操作和应用,以及navigator.clipboard新粘贴板API使用
source link: https://blog.csdn.net/fesfsefgs/article/details/111875639
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

最近的项目上需要做复制粘贴相关的操作,来总结下吧
复制、剪切、粘贴事件:
- copy 发生复制操作时触发;
- cut 发生剪切操作时触发;
- paste 发生粘贴操作时触发;
每个事件都有一个 before 事件对应:beforecopy、beforecut、beforepaste;
这几个 before 一般不怎么用,所以我们把注意力放在三个事件就可以了。
触发条件:
- 鼠标右键菜单的复制、粘贴、剪切;
- 使用了相应的键盘组合键,比如:ctrl+c、ctrl+v;
复制操作:
copy事件使用示例:
<body>
gggwgzgf
</body>
<script type="text/javascript">
document.body.oncopy = e => {
// 监听全局复制 做点什么
console.log(e)
};
</script>
我们可以看到事件对象中的属性:
我们主要研究的是里面的clipboardData
属性对象
clipboardData
对象: 用于访问以及修改剪贴板中的数据
clipboardData对象中有两个方法:
-
getData():
常配合copy事件使用,用于设置到剪贴板中的值 -
setData():
常配合paste事件使用,用于获取设置到剪贴板中的值
兼容:
不同浏览器,所属的对象不同:在 IE
中这个对象是window对象的属性,在Chrome、Safari和Firefox中,这个对象是相应的event对象的属性。所以我们在使用的时候,需要做一下如下兼容:
document.body.oncopy = e => {
let clipboardData = e.clipboardData || window.clipboardData;
// 获取clipboardData对象 + do something
};
copy配合getSelection实现复制某段文本:
<body>
gggwgzgf
</body>
<script type="text/javascript">
document.body.oncopy = e => {
console.log(window.getSelection().toString())
let copyMsg = window.getSelection().toString()
//把值设置到剪贴板中,方便paste事件触发去拿
e.clipboardData.setData("Text", copyMsg);
};
</script>
为了方便,这次,我直接使用ctrl+c测试了
注意:window.getSelection().toString()
我是调用toString()
方法转成文本的,如果不调用这个方法,直接通过window.getSelection()
取到值存到剪贴板会有出奇的效果,后面会说到,需要配合paste事件
粘贴paste事件
使用示例:
<body>
gggwgzgf
<input placeholder="这里存放粘贴操作的值" />
</body>
<script type="text/javascript">
document.body.oncopy = e => {
console.log(window.getSelection().toString())
let copyMsg = window.getSelection().toString()
e.clipboardData.setData("Text", copyMsg);
};
document.body.onpaste=function(e){
var data = e.clipboardData.getData("Text")
document.querySelector("input").value = data
}
</script>
到这里,你可能有个疑问,只能复制粘贴文本吗,图片可以吗?
这是可以的。
通过patse事件获取剪切板中的图片:
<script type="text/javascript">
document.addEventListener('paste', function(event) {
var items = (event.clipboardData && event.clipboardData.items) || [];
var file = null;
if(items && items.length) {
for(var i = 0; i < items.length; i++) {
if(items[i].type.indexOf('image') !== -1) {
file = items[i].getAsFile();
break;
}
}
}
console.log(file)
});
</script>
解释: 当粘贴事件触发时遍历剪切版对象(clipboardData)
中的所有items
,找到类型为图片的item
并调用getAsFile
方法得到文件对象
拿到file
对象后我们有几种选择:
- 通过
fileReader
得到文件对象的base64
字符串
var reader = new FileReader();
reader.onload = function(e){
// 通过e.target.result取到base64然后上传
// 作为src设到image标签上预览
}
reader.readAsDataURL(file); //此处的file为上面得到的文件对象```
- 通过
formData
文件对象转换为二进制数据
var formData = new FormData();
formData.append('file', file);
- 通过
URL.createObjectURL
转成url地址预览
var blobUrl=URL.createObjectURL(file)
示例代码:
<body>
<img src="" id="imgTest" />
</body>
<script type="text/javascript">
document.addEventListener('paste', function(event) {
var items = (event.clipboardData && event.clipboardData.items) || [];
var file = null;
if(items && items.length) {
for(var i = 0; i < items.length; i++) {
if(items[i].type.indexOf('image') !== -1) {
file = items[i].getAsFile();
break;
}
}
}
var blobUrl = URL.createObjectURL(file);
document.getElementById("imgTest").src = blobUrl;
});
</script>
进阶用法:
配合window.getSelection(),文字图片混合复制粘贴:
<body>
<span>gegegseraw</span>
<img src="a1.png" width="100" />
<hr />
下面为粘贴区域:
<div></div>
</body>
<script type="text/javascript">
document.body.oncopy = function(e) {
let copyMsg = window.getSelection()
e.clipboardData.setData("Text", copyMsg);
}
document.body.addEventListener('paste', function(event) {
var data = (event.clipboardData && event.clipboardData.items) || [];
console.log(data)
let div = document.querySelector("div")
for(var i = 0; i < data.length; i += 1) {
if((data[i].kind == 'string') &&
(data[i].type.match('^text/plain'))) {
// This item is the target node
console.log("... Drop:plain")
} else if((data[i].kind == 'string') &&
(data[i].type.match('^text/html'))) {
// Drag data item is HTML
data[i].getAsString(function(s) {
div.innerHTML = s
});
console.log("... Drop: HTML");
} else if((data[i].kind == 'string') &&
(data[i].type.match('^text/uri-list'))) {
// Drag data item is URI
console.log("... Drop: URI");
} else if((data[i].kind == 'file') &&
(data[i].type.match('^image/'))) {
// Drag data item is an image file
console.log("... Drop: File ");
}
}
});
</script>
效果:
navigator.clipboard介绍:
异步剪贴板 API
是一个相对较新的 API
,浏览器仍在逐渐实现它。由于潜在的安全问题和技术复杂性,大多数浏览器正在逐步集成这个 API
。剪贴板 Clipboard API
为 Navigator
接口添加了只读属性 clipboard
,该属性返回一个可以读写剪切板内容的 Clipboard
对象。 在 Web
应用中,剪切板 API
可用于实现剪切、复制、粘贴的功能。
系统剪贴板暴露于全局属性 Navigator.clipboard
之中,Navigator.clipboard
对象中有四个常用方法:都是异步的
read():
从剪贴板读取数据(比如图片),返回一个 Promise 对象。readText():
从操作系统读取文本,返回一个 Promise 对象。write():
写入任意数据至操作系统剪贴板,返回一个 Promise 对象。writeText():
写入文本至操作系统剪贴板,返回一个 Promise 对象。
注意:只有在用户事先授予网站或应用对剪切板的访问许可之后,才能使用异步剪切板读写方法。许可操作必须通过取得权限 Permissions API 的
"clipboard-read"
和/或"clipboard-write"
项获得。
使用实例:
复制writeText():
navigator.clipboard.writeText('要复制的文本')
.then(() => {
console.log('文本已经成功复制到剪切板');
})
.catch(err => {
// 如果用户没有授权,则抛出异常
console.error('无法复制此文本:', err);
});
async,await优化写法:
async function copyPageUrl() {
try {
await navigator.clipboard.writeText(location.href);
console.log('Page URL copied to clipboard');
} catch (err) {
console.error('Failed to copy: ', err);
}
}
粘贴readText():
navigator.clipboard.readText()
.then(text => {
console.log('Pasted content: ', text);
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
同理也可写成async,await
write()写入数据/图片:
function setClipboard(text) {
let data = new DataTransfer();
data.items.add("text/plain", text);
navigator.clipboard.write(data).then(function() {
/* success */
}, function() {
/* failure */
});
}
代码创建了一个 DataTransfer
对象,要替换的内容存储在这里。执行 DataTransferItemList.add()
将数据写入进去,然后执行 write()
方法,指定执行成功或错误的结果。
read()读取数据/图片:
navigator.clipboard.read().then(data => {
for (let i=0; i<data.items.length; i++) {
if (data.items[i].type != "text/plain") {
alert("Clipboard contains non-text data. Unable to access it.");
} else {
textElem.innerText = data.items[i].getAs("text/plain");
}
}
});
实现类知乎/掘金复制大段文本添加版权信息:
<body>
<span>0123456789abcdefg</span>
<hr /> 下面为粘贴区域:
<div></div>
</body>
<script type="text/javascript">
document.body.oncopy = event => {
event.preventDefault(); // 取消默认的复制事件
let textFont = null
let copyFont = window.getSelection().toString(); // 被复制的文字 等下插入
// 防知乎掘金 复制一两个字则不添加版权信息 超过一定长度的文字 就添加版权信息
if(copyFont.length > 10) {
textFont =`
内容: ${copyFont}
作者:codingWeb
链接:https://blog.csdn.net/fesfsefgs
来源:csdn
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。`
} else {
textFont = copyFont; // 没超过十个字 则采用被复制的内容。
}
event.clipboardData.setData('text', textFont); // 将信息写入粘贴板
};
document.body.onpaste = function(event) {
var data = event.clipboardData.getData("text")
document.querySelector("div").innerHTML = data
}
</script>
实现类起点网的防复制功能:
- 禁止复制+剪切
- 禁止右键,右键某些选项:全选,复制,粘贴等。
- 禁用文字选择,能选择却不能复制,体验很差。
- 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;
}
提示: 使用e.preventDefault()
也可以禁用,示例中document.body
全局都禁用了,也可以对 dom(某些区域)
进行禁用。
点击复制功能:
不能使用 clipboardData:
在 IE 中可以用
window.clipboardData.setData('text','内容')
实现。因为,在 IE
中clipboardData
是window
的属性。而其他浏览器则是相应的event
对象的属性,这实际上是一种安全措施,防止未经授权的访问,为了兼容其他浏览器,所以我们不能通过clipboardData
来实现这种操作。
具体做法:
- 创建一个隐藏的input框
- 点击的时候,将要复制的内容放进input框中
- 选择文本内容input.select()
- 这里只能用input或者textarea才能选择文本。
- document.execCommand(“copy”),执行浏览器的复制命令。
<body>
<button>#aaaaaa</button>
<button>#bbbbbb</button>
<button>#ffffff</button>
<input />
</body>
<script type="text/javascript">
function copyText(e) {
var text = e.target.innerHTML; // 获取要复制的内容也可以传进来
var input = document.querySelector('input'); // 获取隐藏input的dom
input.value = text; // 修改文本框的内容
input.select(); // 选中文本
document.execCommand('copy'); // 执行浏览器复制命令
console.log('复制成功');
}
document.body.onclick=copyText
</script>
如果不通过手动点击元素触发click
事件,代码控制,我们都知道,可以使用dom.click()
触发一次点击操作
那别的事件也可以通过代码控制触发吗?
答案是可以的
function trigger(el,type){
let ev = document.createEvent("HTMLEvents")
ev.initEvent(type,true,true)
el.dispatchEvent(ev)
}
使用:
trigger(domEle,"copy")
trigger(domEle,"paste")
Recommend
-
97
JavaScript复制内容到剪贴板
-
49
GitHub is where people build software. More than 27 million people use GitHub to discover, fork, and contribute to over 80 million projects.
-
32
-
28
每日前端夜话 第332篇 翻译: 疯狂的技术宅 作者:Sanwar ranwa 来源:dzone 正文共:1376 字 预...
-
7
阿航 2020年5月30日
-
9
一、简介 浏览器允许 JavaScript 脚本读写剪贴板,自动复制或粘贴内容。 一般来说,脚本不应该改动用户的剪贴板,以免不符合用户的预期。但是,有些时候这样做确实能够带来方便,比如"一键复制"功能,用户点击一下按...
-
13
需求如下:将index.txt 的内容进行格式转换后复制到剪贴板。index.txt莲子心中苦,梨儿腹内酸。--明末清初.金圣叹 雨入花心,自成甘苦。水归器内,各现方圆。--明末清初.金圣叹 真读书人天下少,不...
-
5
浏览器允许 JavaScript 脚本读写剪贴板,自动复制或粘贴内容,而这一切都是通过 navigator clipboard 的 API 来实现的。剪贴板可以用于存储数据并在应用程序内部或应用程序之间使用的临时空间。这些操作的 API 都是异步操作并返回一个 promi...
-
2
headers字符串转字典 并储存在headers.json 复制到剪贴板-Python程序-效果演示发布于 今天 03:53 代码效果...
-
3
JavaScript 剪贴板 Clipboard 的那些事儿! 推荐 原创 减轻阅读负担,启发创作心智,轻松学习 JavaScript 技巧,日拱一卒,jym,...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK