JS - 获取剪切板内容 Clipboard API

目录

  • 1,需求
    • 最终效果
  • 2,实现
    • 示例
  • 3,注意点
    • 1,只支持安全上下文环境
    • 2,只能读取当前页面的剪切板
    • 3,权限获取问题
    • 4,获取内容的 MIME_TYPE 问题
      • 1,文本内容
      • 2,图片内容
    • 5,只能获取剪切板内容的 blob 类型
    • 6,`URL.revokeObjectURL` 的时机
  • 4,其他
    • paste 事件简单举例

1,需求

一个问题咨询表单页,可以上传图片。因为有截图的场景,所以需要得先截图保存在本地再上传,比较繁琐。

想从剪切板获取截图后,直接上传。

最终效果

在这里插入图片描述

2,实现

从剪切板获取的内容分为文本和非文本,分别对应2个API,

  • navigator.clipboard.readText()
  • navigator.clipboard.read(),可以用它来获取图片。

获取的内容是 ClipboardItem 对象。

示例

完整代码:

<template><div ref="refPasteBox"></div><button @click="getClipImg">获取剪切板图片</button>
</template><script setup lang="ts">
import { ref } from "vue";const refPasteBox = ref<HTMLDivElement>();
const getClipImg = async () => {try {const clipboardContent = await navigator.clipboard.read();const clipboardItem = clipboardContent[0];let noImg = true;for (const type of clipboardItem.types) {if (type === "image/png") {noImg = false;const blob = await clipboardItem.getType(type);const url = URL.createObjectURL(blob);// 如果需要 File 对象const file = new File([blob], "clipboard-image.png", { type });console.log(file);const img = document.createElement("img");img.src = url;img.width = 300;img.onload = () => {URL.revokeObjectURL(img.src);};refPasteBox.value?.appendChild(img);}}if (noImg) {alert("当前剪切板中没有图片。\n Windows 系统可通过快捷键\n ⌘+V \n查看剪切板");}} catch (err: any) {if (err.name === "NotAllowedError") {console.log("用户拒绝了访问剪贴板");} else {console.error("无法读取剪贴板内容: ", err);}}
};
</script>

3,注意点

1,只支持安全上下文环境

安全上下文,可以简单理解为只支持 https 协议和本地 http://127.0.0.1http://localhost

http 环境下是 undefined

在这里插入图片描述

2,只能读取当前页面的剪切板

有5个区域:

  1. 页面内容显示区域
  2. 地址栏
  3. 书签栏
  4. 控制台
  5. 其他应用

在这里插入图片描述

在执行 await navigator.clipboard.read() 相关 API 时,必须聚焦到区域1,否则会有如下报错!

在这里插入图片描述

正常情况下通过按钮点击来执行 API 时,都是满足的。

如果想在控制台中简单测试,可以用计时器。在控制台执行后,迅速点击页面区域就可以正常执行。

setTimeout(async () => {const clipboardContent = await navigator.clipboard.read();console.log(clipboardContent);
}, 2000);

3,权限获取问题

当第一次请求剪切板【读权限】时,也就是执行 await navigator.clipboard.read() 时,会弹出确认弹窗:

在这里插入图片描述

允许后就可以正常使用了。如果禁止了,无法通过再次执行代码打开该弹窗!只能手动重置权限。

在这里插入图片描述

4,获取内容的 MIME_TYPE 问题

const getClipImg = async () => {try {const clipboardContent = await navigator.clipboard.read();const clipboardItem = clipboardContent[0];console.log(clipboardItem);for (const type of clipboardItem.types) {if (type === "image/png") {const blob = await clipboardItem.getType(type);}}} catch (err) {console.log(err)}
};

示例代码中,通过 for 循环获取了剪切板内容的 type,它有几个特点:

1,文本内容

无论是从什么地方手动复制的文本,type 都是2个:text/plaintext/html

在这里插入图片描述

2,图片内容

1,如果是截图,type 统一为 image/png

在这里插入图片描述

2,如果是从网页上复制的图片(无论原图片是什么格式),type 统一都是2个:text/htmlimage/png

在这里插入图片描述

在这里插入图片描述

所以,只需要判断 MIME 类型为 image/png 即可获取对应的图片。

另外,从本地复制的文件(图片,excel等) 无法通过 await navigator.clipboard.read() API 获取。

5,只能获取剪切板内容的 blob 类型

// ...
for (const type of clipboardItem.types) {if (type === "image/png") {const blob = await clipboardItem.getType(type);}
}

通过 getType 可以获取剪切板的内容,结果为 blob 类型,

如果需要预览,需要转换为 url

const url = URL.createObjectURL(blob);

如果需要 File 对象(比如上传),需要手动转换。

const file = new File([blob], "clipboard-image.png", { type });

6,URL.revokeObjectURL 的时机

if (type === "image/png") {const blob = await clipboardItem.getType(type);const url = URL.createObjectURL(blob);const img = document.createElement("img");img.src = url;img.width = 300;img.onload = () => {URL.revokeObjectURL(img.src);};document.body.appendChild(img);
}

当通过 URL.createObjectURL() 创建可用于预览的对象 url 后,不能通过 URL.revokeObjectURL 立即释放该对象,否则图片无法显示。需要等到图片加载完成才行,或者不释放问题也不大。

4,其他

剪切板 API 获取的内容,和 paste 事件得到的内容是有区别的。

paste 事件一般用于富文本编辑,粘贴各种类型的文件。

  • 剪切板不能获取本地复制的文件,paste 事件可以。
  • MIME 类型问题,从网页复制的是 type/html,但却可以获取 File 对象。为了兼容,应该用 event.clipboardData?.files[0] 并加判断,而不是 items[0].getAsFile(), getAsFile-参考。
  • 获取的 DataTransfer 对象,虽然 MDN 上的解释是拖动获取的内容,但其实也是粘贴事件获取的内容。

paste 事件简单举例

注意,ClipboardEvent 对象中部分内容通过 console.log 是看不到输出的,类似打印 currentTarget 得到的是 null,但是可以使用的。

<template><div ref="refClipBox" class="clip-box" @paste="getPasteImage" contenteditable="true"></div>
</template><script setup lang="ts">
import { ref } from "vue";const refClipBox = ref<HTMLDivElement>();
function getPasteImage(event: ClipboardEvent) {event.preventDefault();console.log(event);// 检查剪贴板项目const items = event.clipboardData?.items || [];if (items[0].type.indexOf("image") === 0 || items[0].type === "text/html") {// const blob = items[0].getAsFile();const blob = event.clipboardData?.files[0];const url = URL.createObjectURL(blob);const img = document.createElement("img");img.src = url;img.width = 300;img.onload = () => {URL.revokeObjectURL(img.src);};refClipBox.value?.appendChild(img);} else {console.log("不是图片");}
}
</script>
<style>
.clip-box {width: 300px;height: 300px;border: 1px solid #000;
}
</style>

以上。

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/423069.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.C++入门(内联函数,c++11,auto,范围for,nullptr)

⭐本篇文章为C学习的第三篇&#xff1a;主要了解内联函数和部分c11新特性 ⭐本人c代码的Gitee仓库&#xff1a;c学习 橘子真甜/yzc的c学习 - 码云 - 开源中国 (gitee.com) 一. 内联函数 以inline修饰的函数称为内联函数&#xff0c;编译的时候c编译器会在内联函数的地方展开&a…

【GBase 8c V5_3.0.0 分布式数据库常用维护命令】

一、查看数据库状态/检查&#xff08;gbase用户&#xff09; 1.gha_ctl monitor 使用gha_ctl monitor查看节点运行情况(跟dcs的地址和端口) gha_ctl monitor -c gbase -l http://172.20.10.8:2379 -Hall |coordinator | datanode | gtm | server|dcs:必选字段。指定查看哪类集…

【有啥问啥】探索扫地机器人中的 SLAM 算法:原理、实现与未来展望

探索扫地机器人中的 SLAM 算法&#xff1a;原理、实现与未来展望 随着智能家居的普及&#xff0c;扫地机器人逐渐成为日常生活中的常见家电。其自主导航能力使得它能够在复杂的家庭环境中高效完成清洁任务&#xff0c;而这背后的核心技术之一就是 SLAM&#xff08;Simultaneou…

【文件包含】——日志文件注入

改变的确很难&#xff0c;但结果值得冒险 本文主要根据做题内容的总结&#xff0c;如有错误之处&#xff0c;还请各位师傅指正 一.伪协议的失效 当我们做到关于文件包含的题目时&#xff0c;常用思路其实就是使用伪协议&#xff08;php:filter,data,inpput等等&#xff09;执行…

shader 案例学习笔记之step函数

step函数 参数是float step(edge,x)&#xff1a;当x>edge时返回1&#xff0c;否则返回0 #ifdef GL_ES precision mediump float; #endifuniform vec2 u_resolution;void main(){vec2 st gl_FragCoord.xy/u_resolution.xy;float f step(0.5, st.x);gl_FragColor vec4(f…

算法知识点————数论【最大公约数】【快速幂】【分解质因数】

结论1&#xff1a;两个互质的整数mn不能凑出的最大整数是(n-1)(m-1) -1 结论2:一个数的因数可以拆成n个质因数的乘积。 黄金分割&#xff1a;0.61803399 在数论中&#xff0c;如果两个或两个以上的整数的最大公约数是 1 &#xff0c;则称它们为互质。 最大公约数: 两数乘积最…

C语言:结构体

在前面我们已经介绍了整形&#xff0c;浮点型&#xff0c;字符型&#xff0c;还介绍了数组&#xff0c;字符串。但是在实际问题中只有这些数据类型是不够的&#xff0c;有时候我们需要其中的几种一起来修饰某个变量&#xff0c;例如一个学生的信息就需要学号&#xff08;字符串…

基础 Web 开发

1. 构建项目&#xff1a; 2.添加依赖 <dependencies> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupI…

[ RK3566-Android11 ] 关于 RK628F 驱动移植以及调试说明

问题描述 我这个项目的SDK比较老&#xff0c;移植RK628F最新驱动的调试过程&#xff0c;踩了很多坑&#xff0c;希望大家别踩坑。 解决方案&#xff1a; 首先在FTP上下载最新的RK628的驱动 rk628-for-all-v27-240730 版本。 下载完后 不要直接替换&#xff0c;不要直接替换&a…

网络高级(学习)2024.9.10

目录 一、Modbus简介 1.起源 2.特点 3.应用场景 二、Modbus TCP协议 1.特点 2.协议格式 3.MBAP报文头 4.功能码 5.寄存器 &#xff08;1&#xff09;线圈寄存器&#xff0c;类比为开关量&#xff0c;每一个bit都对应一个信号的开关状态。 &#xff08;2&#xff09…

中学生考试成绩在线查询系统

时代在发展&#xff0c;社会在进步&#xff0c;传统的成绩发布方式已经显得力不从心了。老师们&#xff0c;是时候尝试一种更高效、更安全的成绩查询方式了。 还在为如何保护学生隐私而头疼&#xff1f;还在担心成绩的公平性和准确性&#xff1f;易查分小程序将这些这些问题都将…

安卓13禁止声音调节对话框 删除音量调节对话框弹出 屏蔽音量对话框 android13

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析3.1 方法13.2 方法24.代码修改4.1 代码修改方法14.2 代码修改方法25.编译6.彩蛋1.前言 客户需要,调整声音,不显示声音调节对话框了。我们在系统里面隐藏这个对话框。 2.问题分析 android在调整声音的…

部署Tomcat和抓包

部署Tomcat 复制文件到桌面 查看自己是否有java环境&#xff0c;下图所示是有的&#xff0c;若没有需另行下载 解压tomcat文件 tar -xzvf apache-tomcat-7.0.96.tar.gz 下列为tomcat文件的几个重要文件 进入到bin文件中 启动tomcat ./startup.sh 可以先用本机查看是否启动…

戴尔14代服务器配置IDRAC9远程配置说明

一、规划管理网段 规划管理网段&#xff0c;要求如下&#xff1a; 管理网段与业务网段不能使用同一网段&#xff1b;管理网段与业务网段不能直接互通&#xff1b;如有条件管理网与业务网使用不同设备接入。 二、配置服务器idrac 2.1、确认idrac口位置 2.2、开机进F2 2.3、 …

java程序员入行科目一之CRUD轻松入门教程(一)

之前在操作MySQL的时候&#xff0c;都是采用Navicat&#xff0c;或者cmd黑窗口。 无论使用什么方式和MySQL交互&#xff0c;大致步骤是这样的 建立连接&#xff0c;需要输入用户名和密码编写SQL语句&#xff0c;和数据库进行交互 这个连接方式不会变&#xff0c;但是现在需要 基…

(学习总结16)C++模版2

C模版2 一、非类型模板参数二、模板的特化1. 概念2. 函数模板特化3. 类模板特化全特化偏特化类模板特化应用示例 三、模板分离编译1. 什么是分离编译2. 模板的分离编译3. 解决方法 模板总结 以下代码环境为 VS2022 C。 一、非类型模板参数 模板参数分为类型形参与非类型形参。…

什么是CPU、GPU、NPU?(包懂+会)

目录 举例子 CPU&#xff1a;主厨 GPU&#xff1a;大量的厨房助理 NPU&#xff1a;面包机 总结 讲理论 CPU&#xff08;中央处理器&#xff09; GPU&#xff08;图形处理单元&#xff09; NPU&#xff08;神经网络处理单元&#xff09; 对比分析 举例子 CPU&#xff…

【代码随想录训练营第42期 Day55打卡 - 图论Part5 - 并查集的应用

目录 一、并查集 适用范围 三大基本操作 二、经典题目 题目&#xff1a;卡码网 107. 寻找存在的路径 题目链接 题解&#xff1a;并查集 三、小结 一、并查集 适用范围 动态连通性问题&#xff1a;并查集可以判断两个节点是否在同一个连通分量中&#xff0c;这在处理网络…

C语言——模拟实现strcat

strcat的作用是实现字符串的连接或者追加的 还是老样子我们先学会strcat的使用方式 int main() {char arr[30] "hello ";strcat(arr, "world");printf("%s", arr);return 0; } 库函数的规则了解了&#xff0c;那跟着之前讲过strcpy的逻辑改写。…

C++中的左值(Lvalue)和右值(Rvalue)详解

C中的左值&#xff08;Lvalue&#xff09;和右值&#xff08;Rvalue&#xff09;详解 在C中&#xff0c;左值&#xff08;Lvalue&#xff09;和右值&#xff08;Rvalue&#xff09;的概念是理解表达式和变量的重要基础。为了提高C的性能和灵活性&#xff0c;C11引入了一些新的…