Open yaofly2012 opened 2 years ago
paste
事件window
对象上 // Ctrl+V
useEffect(() => {
if(disabled) {
return;
}
domHelpers.addEventListener(window, 'paste', handlePaste);
function handlePaste(e) {
const { files } = e.clipboardData || window.clipboardData || {};
if(files && files.length) {
// 执行上传文件操作
}
}
return () => {
domHelpers.removeEventListener(window, 'paste', handlePaste);
}
}, [disabled])
Ctrl + V
即可;window
对象上的,所以只适用页面里只有一个上传文件入口的场景。textarea/input/或者
contenteditable="true"`元素上可以处理同时存在多个上传文件的场景,但是:
Navigator.clipboard
API主要解决命令式的(比如点击“粘贴”按钮)触发粘贴操作。
async function handlePaste() {
try {
const items = await navigator.clipboard.read();
const blobs= await Promise.all(items
.filter(item => item.types && /^image/.test(item.types[0]))
.map(item => item.getType(item.types[0])))
// Blob转成File
const files = blobs.map(blob => {
const file = new File(
[blob],
blob.type.replaceAll('/', '.'),
{
type: blob.type,
lastModified: Date.now()
}
)
return file;
})
if(files.length) {
// 上传文件操作
}
} catch(e) {
console.error(e);
}
}
Blob
转成File
?我们项目里如果不把Blob
转成File
,则接口是不能正确处理图片(具体原因是接口通过filename
获取文件扩展名)。
如果不转化,上传文件时数据内容是:
------WebKitFormBoundaryWKBAIMO2nAdjCFX0
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: image/png
xxxxx...
------WebKitFormBoundaryWKBAIMO2nAdjCFX0--
转化后,上传文件时数据内容是:
------WebKitFormBoundaryOWXckuaZauCoJffm
Content-Disposition: form-data; name="file"; filename="image.png"
Content-Type: image/png
xxxxxx...
------WebKitFormBoundaryOWXckuaZauCoJffm--
差异点就是Content-Disposition
的filename
取值,即不转化文件名统一是blob
,如果转化则可以自定义个文件名。
Blob
PK File
首先要看实际项目需要:
Content-Disposition
的filename
的值(比如通过filename
获取文件扩展名)?
一、背景
项目里有个上传图片的功能,但用户经常上传截屏图片,此时用户的操作流程是
截屏 -> 保存图片-> 选择图片并上传
。为了用户体验也为了实现产品吹的牛皮,需要将3步改成2步,即截屏 ->上传
。技术调研
截屏操作获取的图片存储在系统剪切板,所以得利用JS读取剪切板内容。研究下Clipboard API的使用。
测试环境
二、
Navigator.clipboard
利用全局属性
Navigator.clipboard
可以利用JS操作系统剪切板。使用限制
JS方式读写系统剪切板涉及用户隐私和数据安全问题,这个API使用场景有使用限制:
安全上下文(HTTPS) 必须是
HTTPS
或者localhost
域名,否则不会暴露Navigator.clipboard
属性:用户授权
文档要处于
Focused
状态,否则报错:文档如果以
iframe
方式被嵌入其他跨域文档中,则也不能执行详情见弃用跨域 iframe 中的权限
读数据
Clipboard.read()
三、粘贴(paste)事件
监听用户触发的粘贴操作。此时粘贴操作是用户主动触发的,所以排除了一些安全问题。
使用限制对比
Navigator.clipboard
APIClipboardEvent.clipboardData
属性ClipboardEvent.clipboardData
属性可以获取系统剪切板的数据。 总结下ClipboardEvent.clipboardData
对象的几个比较重要的属性和方法:text/plain
,text/html
,Files
等types
属性的值一一对应files
属性)实战
获取文本内容
获取富文本内容
即copy带有样式的文本。
获取并展示粘贴板数据
根据
types
属性的值读取剪切板数据。兼容性
目前测试Chrome(V87),FF(V95)可以正常使用。详情见兼容性
参考