复制剪切板

404 阅读1分钟

业务中复制到剪切板的实现方式:

1、Clipboard API

function copyToClipboard(text) {
    navigator.clipboard.writeText(text)
        .then(() => {
            console.log('Copied to clipboard');
        })
        .catch((error) => {
            console.error('Error copying to clipboard:', error);
        });
}

这个函数会调用Clipboard API的writeText方法,将文本内容作为参数传递给该方法,并返回一个Promise对象。如果复制操作成功,Promise对象的then方法会被调用,如果复制操作失败,Promise对象的catch方法会被调用。

注意:这段代码只能在HTTPS协议的安全环境下使用

2、document.execCommand

当前API不再推荐使用该特性。虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留。

function execCommand(text: string) {
    const input = document.createElement("textarea");
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();

    try {
        return document.execCommand("copy"); // 部分浏览器废除了;
    } catch (e) {
        return false;
    } finally {
        document.body.removeChild(input);
    }
}

这个函数的意思是创建一个textarea插入到body下 然后用document.execCommand("copy")复制,之后在删除。

3、window.clipboardData

一些早期版本的ie浏览器可以使用这个api 兼容低版本的ie浏览器

window.clipboardData.setData('Text', 'Hello, world!');

完整代码:

// 自定义hooks
function execCommand(text: string) {
    const input = document.createElement("textarea");
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();

    try {
        return document.execCommand("copy"); // 部分浏览器废除了;
    } catch (e) {
        return false;
    } finally {
        document.body.removeChild(input);
    }
}

async function clipboard(text: string) {
    try {
        // 请求剪贴板写入权限 需要https才能启用
        const permissionStatus = await navigator.permissions.query({
            name: "clipboard-write" as PermissionName,
        });
        if (permissionStatus.state !== "granted") {
            return;
        }

        // 将文本写入剪贴板
        await navigator.clipboard.writeText(text);
        return true;
    } catch (error) {
        return false;
    }
}

// 检查当前浏览器支持不支持document.execCommand("copy")
function requestClipboardPermission() {
    if (
        document.queryCommandSupported &&
        document.queryCommandSupported("copy")
    ) {
        return true;
    } else {
        return false;
    }
}

export function useCopyToClipboard() {
    const copy = (text: string) => {
        if (!requestClipboardPermission()) {
            return clipboard(text);
        }else if (window.clipboardData) {
            return window.clipboardData.setData('Text', clipboardData.text); 
        } else {
            return execCommand(text);
        }
    };
    return { copy };
}

常用的clipboard.js源码也是这样方式实现的。