头图
最近有个小需求,点击页面上的复制链接按钮,把当前页面的地址复制到剪贴板,方便粘贴到其他地方分享。

是否有现成的库?

当然有了,比如clipboardjs,体积小,而且可以灵活的引入到项目中。

不过,如果你和我一样对这个功能的实现很好奇,可以接着向下看,其实也很简单。

JS复制内容到剪贴板的实现

如果在百度中这样搜索,得到的答案大部分都是教你使用下面这个方法:

document.execCommand('copy')

不过如果去查阅一下比较权威的文档如 MDN、Stack Overflow,就会发现上面的方法已经被废弃了,已经不推荐使用,因为不能确定哪一天就真的用不了了。

所以应该找一种稳妥的方式实现这个功能,Stack Overflow 上有这样一个回答个人认为比较不错,贴下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

<button onclick="copyTextToClipboard(window.location.href)">复制链接</button>
<script>

    function fallbackCopyTextToClipboard() {
        // 1.创建一个可选中元素
        let textArea = document.createElement("textarea");
        textArea.value = window.location.href;
        // 2.使用定位,阻止页面滚动
        textArea.style.top = "0";
        textArea.style.left = "0";
        textArea.style.position = "fixed";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Fallback: Copying text command was ' + msg);
        } catch (err) {
            console.error('Fallback: Oops, unable to copy', err);
        }
        // 3.移除元素
        document.body.removeChild(textArea);
    }

    function copyTextToClipboard(text) {
        if (!navigator.clipboard) {
            fallbackCopyTextToClipboard(text);
            return;
        }
        navigator.clipboard.writeText(text).then(function() {
            console.log('Async: Copying to clipboard was successful!');
        }, function(err) {
            console.error('Async: Could not copy text: ', err);
        });
    }
</script>
</body>
</html>

我们可以把上面的方法称为 Async + Fallback (即优先使用navigator.clipboard,如果这种比较新的方式没有被你的浏览器支持,就使用document.execCommand 这个即将被废弃的方式)

原理分析

本质上document.execCommand是在你的页面中创建了一个没有用的DOM元素,如textArea、input,它们的特点是内容可以被选中,然后被document.execCommand操纵,进而复制内容到剪贴板。这种方式看起来并不优雅,所以我们优先推荐navigator.clipboard.writeText(text).then()。如果用户的浏览器还没有支持navigator.clipboard,再将document.execCommand作为候选,这样兼容性比较好。

文章首发于 IICOOM-个人博客 《JavaScript复制内容到剪贴板》


来了老弟
508 声望31 粉丝

纸上得来终觉浅,绝知此事要躬行