复制粘贴

630 阅读3分钟

第一次发表文章,就讲讲曾经写过的一个复制粘贴的功能实现吧。本篇文章不考虑浏览器兼容,谷歌浏览器亲测至少得88版本往上。Mac系统复制粘贴html数据,会自动加一些标签,小伙伴们自己测吧。一般需求用不着。

想要实现复制粘贴就只需要搞明白两件事就可以了。

第一就是如何往粘贴板里边存放数据,第二就是如何读取粘贴板里边的数据。

所操作的数据大致可以分为三类数据 1:字符串 2:带样式的HTML 3:图片 其他数据就请各位童鞋补充吧

第一 如何往粘贴板里边放数据

① 如果只是放普通字符串是最简单的

navigator.clipboard.writeText('通过简单方法,往剪切板写入这句话');

② 想要放入带格式的数据,比如想要往word内粘贴一个表格,跟正常写html标签加写样式是一样的

<button onclick="putHTML2Clipboard()">往粘贴板内放带样式/格式的数据</button>
async function putHTML2Clipboard() {
    const html = `
        <table width="568" style="border-collapse:collapse;">
            <tr>
                <td width="81" style="border: 1.0pt solid red">
                <p>中文</p>
                </td>
                <td width="16" style="border:solid windowtext 1.0pt;">
                <p>另外的单元格</p>
                </td>
            </tr>
        </table>`
    const htmlBlobABC = new Blob([html], { type: "text/html" })
    const item = new ClipboardItem({
        [htmlBlobABC.type]: htmlBlobABC
    })
    await navigator.clipboard.write([item]);
    console.log("HTML数据复制成功,快去word内粘贴试试吧");
}

③往粘贴板内放入图片,目前只支持放png图片

<button onclick="putNetWorkPic2Clipboard()">往粘贴板内放网络图片</button>
async function putNetWorkPic2Clipboard() {
    const imgURL = 'xxx'; // 自己去网上随便找个png的图片,把地址贴这儿就可以
    const data = await fetch(imgURL);
    const anyName = await data.blob();
    await navigator.clipboard.write([
        new ClipboardItem({
            [anyName.type]: anyName,  // 注意这个anyName 任意名字(随便写) 但是要对应上 
        }),
    ]);
    console.log('网络图片复制成功,快去word内粘贴试试吧');
}
<button onclick="putLocalPic2Clipboard()">往粘贴板内放本地图片</button>
async function putLocalPic2Clipboard() {
            const data = await fetch("./pic/testPng.png");
            const anyName = await data.blob();
            // const str = new Blob(["测试用的字符串"], { type: "text/plain" });
            await navigator.clipboard.write([
                new ClipboardItem({
                    [anyName.type]: anyName,  // 注意这个anyName 任意名字(随便写) 但是要对应上 
                    // [str.type]: str,  // 目前也不支持多个
                }),
            ]);
            console.log("执行了");

其实也可以用放HTML的方式,把图片放入粘贴板内

第二:读取粘贴板内的数据

这就比较简单了

<!-- 模拟在这个div区域内按Ctrl + V 粘贴 contenteditable="true" 是允许该div可编辑的意思 可以看到粘贴的结果 -->
<div class="target" contenteditable="true"></div>
const target = document.querySelector("div.target");
target.addEventListener('paste', pasteFun);
// 读取剪切板示例
async function pasteFun(e) {

    // e.preventDefault(); 这里边的return 并不能阻止粘贴 只是阻止下边的程序执行 如果要阻止粘贴行为 就用 阻止默认行为事件 可以自己拿到粘贴板内的数据 自己控制粘贴行为
    const items = await navigator.clipboard.read();
    const item = items[0];
    
    // 如果粘贴板内有HTML类型的数据和纯文本的数据,可以选择要哪种的
    if (item.types.length === 1 && item.types[0] === "image/png") { // 并不能拿到复制的文件夹内的图片
        const imgBlob = await item.getType("image/png"); // 这是拿到了图片的blob数据
        // 然后将图片的blob数据转为base64 就可以使用了
        let reader = new FileReader()
        reader.readAsDataURL(imgBlob)
        reader.onload = (e) => {
            // e.target.result 就是图片的base64
            const base64 = e.target.result;
            const img = document.createElement("img");
            img.src = base64;
            document.body.appendChild(img);
        }
        return
    }
    if (item.types.includes("text/html")) { 
        const htmlBlob = await item.getType("text/html");
        const html = await new Response(htmlBlob).text();
        console.log(html, "html");
        return
    }
    
    // 如果只要纯文本
    const plainBlob = await item.getType("text/plain");
    const plain = await new Response(plainBlob).text();
    console.log(plain, "纯文本");
    
    const resStr = e.clipboardData.getData('text'); // 如果确定只要普通字符串 这个更简单些
    console.log("这应该是获取的文本", resStr)
    
}