Web API Clipboard 使用

在学习 Clipboard API 前先看下 MDN 对它的解释:

剪贴板 Clipboard API 提供了响应剪贴板命令(剪切、复制和粘贴)与异步读写系统剪贴板的能力。从权限 Permissions API 获取权限之后,才能访问剪贴板内容;如果用户没有授予权限,则不允许读取或更改剪贴板内容。

该 API 被设计用来取代使用 document.execCommand() 的剪贴板访问方式。

 可以从 MDN 中的介绍可以看出,它是一个针对剪切板处理而产生的 API,它有四个方法且都是异步的 ( Returns Promise ),promise 的处理结果就是用户是否同意你访问用户的剪切板。 

我用的浏览器是谷歌最新的浏览器,每个浏览器的效果与处理函数会有所不同。

clipboard.read()

该方法返回一个 Promise,里面保存着一份剪切板内容的副本,可以时一切数据类型,可以时图片等。

语法:

const promise = navigator.clipboard.read();

也可以直接处理 Promise,通过 .then ...catch 链式的形式

示例:

需求: 当用户一进入页面,将用户上一次剪切版的内容展示在页面上。

代码:

<div id="display"></div>
<script type="text/javascript">
    const oDiv = document.getElementById('display')
    window.onclick = async () => {
    navigator.clipboard.read().then(clipboardItems => {
        let reader = new FileReader()  // 文件解码器
        console.log(clipboardItems)
        clipboardItems[0].getType('text/plain').then(data => {
             // 二进制数据( Blob ) data 
            reader.onload = e => { // 函数完成后触发的事件
                // 对二进制编码后的结果
                oDiv.innerText = e.target.result
            }
            reader.readAsText(data) // 是一个异步函数
            })
        })
    }
</script>

read() 返回的 Promise 中保存的是一个 clipboardItem[] 数组,MDN 对它的解释是:

剪贴板API的ClipboardItem接口表示通过剪贴板API读取或写入数据时使用的单个项格式。

可以通过它的 getType () 方法返回的 ( Promise ) 可以获取到剪切板的二进制数据(Blob),通过 FileReafer() 文件解码器对二进制数据进行处理。

下面我来说下,我踩的坑。上面的例子中你应该或多或少有一个疑问,为什么是绑 window.onclick 的点击事件,而不是 window.onload 呢?这里就是第一个坑,如果使用 window.onload 控制台会报个错:

Uncaught (in promise) DOMException: Must be handling a user gesture to use custom clipboard

必须处理用户手势才能使用自定义剪贴板,也就是需要页面与用户有交互才行

第二个坑,按照 MDN 中的文档,clipboard.read() 方法可以获取任何数据类型,可我并没有获取到除文本类型以外的数据。查资料也没有什么文档有用(如果有知道的可以私聊我,找资料找的烦死了...)。

clipboard.readText()

 Clipboard 接口的 readText() 方法解析系统剪贴板的文本内容返回一个Promise 。这个方法比 read() 方法方便很多,不过只可以读取文本信息。

需求:与上个例子一致。

代码:

<div id="display"></div>
<script type="text/javascript">
	window.onload = () => {
	    const oDiv = document.getElementById('display')
		navigator.clipboard.readText().then(txt => {
			oDiv.innerText = txt
		})
		.catch(err => {
			// 用户拒绝处理
		})
	}
</script>

 这个方法不必须要用户与页面产生交互,第一次访问的时候会询问用户是否允许网页访问,更具用户的处理结果返回的 Promise 会以 : 同意( resolve ),拒绝( reject )。

clipboard.write()

Clipboard 的方法 write() 写入图片等任意的数据到剪贴板。这个方法可以用于实现剪切和复制的功能。但是你要提前获取 "Permissions API" 的 "clipboard-write" 权限才能将数据写入到剪贴板。

 它有一个参数  DataTransfer 对象包含要写如剪切版的数据。实际上 Chrome 不支持这个对象写入数据,我也查阅过资料,没有一个示例在Chrome 上实现,Chrome上支持 ClipboardItem对象,而且 Chrome 只支持 text/plain 类型的数据写入剪切板,可以写入文件。(可能使用的版本问题!)

需求:选择文件写入剪切板。

代码:

<input type="file" />
<script>
    const oFile = document.querySelector('input[type="file"]')
    oFile.onchange = function () {
        const files = this.files // 获取文件对象数组
	    if (files.length > 0) { // 判断是否有文件对象
		    for (let i = 0; i < files.length; i++) {
			    navigator.clipboard.write([
				    new ClipboardItem({ // 写入剪切版的内容
					    [files[i].type] : files[i]
				    })
			    ])
                    .then(() => {}) // 成功执行
                    .catch(err => {}) // 失败,不一定是用户没有授权
		    }
	    }
    }
</script>

运行打开网页,点击按钮选择一个 .txt 的文件,然后在去粘贴就会发现,粘贴的内容是文本文件的内容。

Uncaught (in promise) DOMException: Type image/jpeg not supported on write.

如果是非 text/plain 的文件对象,会出现类似得异常

 clipboard.writeText()

Clipboard 接口的 writeText() 方法可以写入特定字符串到操作系统的剪切板。

需求:当页面加载完成向用户剪切版写入欢迎您。

代码:

<script type="text/javascript">
	window.onload = () => {
		navigator.clipboard.writeText('欢迎您')
			.then(() => {
				console.log('success')
			})
			.catch(err => {
				console.log(err)
			})
	}
</script>

Clipboard Event 事件

ClipboardEvent 接口描述了与修改剪切板相关信息的事件,这些事件包括 剪切cut , 复制copy 和 粘贴paste 事件。clipboardData 属性中的 DataTransfer 中保存着用户 cut,copy,paste 事件的数据。

copy 用户在网页上产生复制事件,会触发。

例如: 阻止用户复制网页内容。

代码:

<script type="text/javascript">
	document.addEventListener('copy', e => {
		e.preventDefault()
		// 后续处理,提示用户等...
	})
</script>

cut 剪切事件

当用户在网页上 ctl + x 时或者右键剪切都会触发。

例如: 当用户触发事件后,向剪切板中写入版权信息。

代码:

<script type="text/javascript">
	document.addEventListener('cut', e => {
		navigator.clipboard.writeText('相关版权不可剪切')
	})
</script>

paste 粘贴事件

当用户 ctl+v 或右键粘贴时触发。

需求: 监听 input 的粘贴事件,向粘贴的数据后面追加字符。

代码:

<textarea cols="30" rows="20"></textarea>
<script type="text/javascript">
	const oTextArea = document.getElementsByTagName('textarea')[0]
	
	oTextArea.addEventListener('paste', e => {
		e.preventDefault()
		let txt = e.clipboardData.getData('text/plain') + ",功能由某某提供"
		oTextArea.value = txt
	})
</script>

阻止默认事件,自定义处理。

到这里 Clipboard WEB API 就基本学习完了,怎么使用,在哪里应用,就看自己的想法了。

最后相下,下面的效果怎么实现。

具体功能上面都有说,利用的就是上面介绍的 API,外层的 div 是用户可以编辑的(contenteditable) 不过,有一弊端,右边的点击上传框也可以删除,而且第一次必须要点按钮上传。我想 bilibili,csdn的上传应该不是使用用户可编辑的形式,不过就当一个练习啦,加深对 clipboard api 的使用。上述示例中还使用到了拖拽API(drop, dragover)。源码放在 http://www.qylove.asia/code/index.tar,如果访问不了,就是服务器到期了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值