

JavaScript 剪贴板 Clipboard 的那些事儿!
source link: https://blog.51cto.com/u_13961087/5665853
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.

JavaScript 剪贴板 Clipboard 的那些事儿!
推荐 原创减轻阅读负担,启发创作心智,轻松学习 JavaScript 技巧,日拱一卒,jym,冲~
本篇带来 —— JavaScript 剪贴板 Clipboard 的那些事儿!
复制粘贴就是互联网最伟大的发明,无论是使用快捷键 ctrl c 、ctrl v,还是鼠标选中右键复制再粘贴,Copy 操作都是非常简单的。
然而要注意的是,你的剪贴板 Clipboard 或许在被有些软件无时无刻的监听着,有时候在知乎上搜的东西,最终出现在了京东商品的推荐页里,让人不禁打个冷战,疑问道:它怎么知道我想买这个东西的?
在 JavaScript 中 navigator.clipboard
全局对象就是来处理剪贴板的,它有以下方法:
- readText: 读文本
- read: 读任何类型的数据,除文本外还有图片这些;
- writeText: 写文本
- write: 写任何数据;
接下来我们实战来看看 navigator.clipboard
的代码应用:
原生 JS 实现将数据写入剪贴板:
<head>
<script >
async function copyText() {
let textArea = document.getElementById("myText")
const permission = await navigator.permissions.query({ name: 'clipboard-write' });
if (permission.state === 'denied') {
return console.error("Damn, we don't have permissions to do this")
}
try {
await navigator.clipboard.writeText(textArea.value) // 写入文本
console.log("done!")
} catch (e) {
console.error("Error while copying text!")
console.error(e.message)
}
}
</script>
</head>
<body>
<textarea rows="5" cols="89" id="myText"></textarea>
<button onclick="copyText()">Share!</button>
</body>
</html>
这里要注意的是,在我们写入之前要访问 navigator.permissions.query({ name: 'clipboard-write' });
用于提前判断我们是否有权限去做写入操作。
除了写入文本,还可以写入图片:
<head>
<script >
async function copyImg() {
const type = "image/png";
let myImg = document.getElementById("myImage")
let img = await fetch(myImg.getAttribute("src"))
var blob = new Blob([await img.blob()], { type });
var data = [new ClipboardItem({ [type]: blob })];
try {
await navigator.clipboard.write(data)
console.log("The image was copied")
} catch (e) {
console.error("There was a problem copying the imagge")
console.error(e)
}
}
</script>
</head>
<body>
<img src="./img.png" width="300" id="myImage" />
<button onclick="copyImg()">Share!</button>
</body>
</html>
与文本稍有不同的是我们要包装一个 ClipboardItem 数组;
与写入数据对应的就是读取数据:
<head>
<script >
async function pasteImage() {
let destinationImage = document.getElementById("myImage")
const permission = await navigator.permissions.query({ name: 'clipboard-read' });
if (permission.state === 'denied') {
throw new Error('Not allowed to read clipboard.');
}
const clipboardContents = await navigator.clipboard.read();
for (const item of clipboardContents) {
if (!item.types.includes('image/png')) {
throw new Error('Clipboard contains non-image data.');
}
const blob = await item.getType('image/png');
destinationImage.src = URL.createObjectURL(blob);
}
}
</script>
</head>
<body>
<img width="300" id="myImage" />
<button onclick="pasteImage()">Get Image!</button>
</body>
</html>
同样需要先确认是否有权限读取:navigator.permissions.query({ name: 'clipboard-read' })
读取图片要用到:URL.createObjectURL
方法。
混淆剪贴内容
这里再提供一个小技巧:假设我们不想自己的文本内容被复制,除了禁止复制以外,还可以用 JS 脚本设置给它赋值一个内容混淆过的内容。
代码如下:
<head>
<script >
function setUpEvent() {
let mainContent = document.getElementById("main-content")
mainContent.addEventListener('copy', function(evt) {
let selectedText = document.getSelection()
selectedText = selectedText
.toString()
.split("") //turn it into an array of characters
.sort((a,b) => Math.random() > 0.5?1:-1) //shuffle the array
.join("") //join it back into a single string
evt.clipboardData.setData("text/plain", selectedText) //set the clipboard's data
evt.preventDefault()
})
}
</script>
</head>
<body onload="setUpEvent()">
<p id="main-content">
For this example, I'm using the HTML IMG tag just to get the src atttribute, since I can't really use the element directly. The API needs me to turn the image into a Blob (which is essentially a way of saying "It's a big chunk of I don't know exactly"). And since the DOM API doesn't have any methods I can use, I'm fetching the actual image and the calling the blob method on the response object (line 11).
The rest is as expected, I create a one-element array with a ClipboardItem containing the blob, and the I write the array into the clipboard.
You can use the above example to extrapolate how you would go about copying something else, like an XLS file. You need to fetch it, blob it, and make sure you used the right mime-type, which is the string I have on the type variable. If you don't know what's the mime-type for your file, just Google "mime-type for <your file's extension here>" and you'll have it.
</p>
</body>
</html>
我们可以在 https://www.runoob.com/runcode 即时运行这段代码看看混淆后的剪贴板的内容:
粘贴出来是这样的:

主要用到了随机数去打乱内容。
挺有意思的,不是让人不能复制,而是让人复制一个乱序的结果,Clipboard 也能这样玩儿~~
OK,以上便是本篇分享。点赞关注评论,为好文助力👍
我是掘金安东尼 🤠 100 万人气前端技术博主 💥 INFP 写作人格坚持 1000 日更文 ✍ 关注我,安东尼陪你一起度过漫长编程岁月 🌏
Recommend
-
151
面试的时候,面试官问,你是怎么理解面向对象的编程?我想很多人会照着面试题来背吧,面向对象呀,不就是继承,封装,多态吗?注意,面试官问到这里,是想听听你对面向对象的理解,而不是让你来背概念。面向对象,是对现实世界的模拟,下图我们简单模拟了一个动物...
-
151
ArrayList部分一共五篇文章了,并且引入了时间复杂度来分析,强烈建议大家一定要按顺序阅读,本文是第1篇。前些天的文章,反复的画图,不停的重复,就是想让大家理解,对象在内存中是什么样的。也是为今天的及以后的讲解打下基础。如果要说大家在写Java代码的时候...
-
157
ArrayList部分一共五篇文章了,并且引入了时间复杂度来分析,强烈建议大家一定要按顺序阅读,本文是第3篇,前两篇文章分别是:1、ArrayList初始化 - Java那些事儿专栏2、ArrayList底层数组扩容原理 - Java那些事儿专栏最近看了一下评
-
91
-
134
前言前端的工作并不仅仅是实现「视觉&交互稿」,想要开发一个高性能易维护的「完美」站点并未易事,针对前端的性能优化贯穿着项目开发的始终,绝不是交互口中的「拖拽工人」! 然而前端优化策略却是一件老生常谈的问题,百度一把大量的博文,曾拜读过张成...
-
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.
-
15
最近的项目上需要做复制粘贴相关的操作,来总结下吧 复制、剪切、粘贴事件: copy 发生复制操作时触发;cut 发生剪切操作时触发;paste 发生粘贴操作时触发;每个事件都有一个 before 事件对应:befo...
-
7
阿航 2020年5月30日
-
10
一、简介 浏览器允许 JavaScript 脚本读写剪贴板,自动复制或粘贴内容。 一般来说,脚本不应该改动用户的剪贴板,以免不符合用户的预期。但是,有些时候这样做确实能够带来方便,比如"一键复制"功能,用户点击一下按...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK