JS实现剪切板操作

简介: JS实现剪切板操作

JS实现剪切板操作

在网上找到很多种方法,ZeroClipboard.js、clipboard.js插件等,但是都没有办法解决本人项目中的问题,最后发现可以通过navigator对象得到clipboard,进行剪切板操作

先来一下clipboard.js版本的热热身。

1. clipboard.js

1.1 通过text的function()来复制内容

<!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 id="btn">Copy</button>

    <script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    <script>
      const clipboard = new ClipboardJS('#btn', {
        // 第一个参数是可以是类似jQuery的选择器,也可以是DOM对象
        text: function () {
          return 'Hello World'; // 返回要放到剪切板的内容
        },
      });
    </script>
  </body>
</html>

image-20211208003450259

1.2 通过target的function()来复制内容

类似上面的,不过创建clipboard对象时第二个参数的对象的属性从text变为了target。简单理解的话,就是text就相当于是直接把要复制的内容给出来,而target则是把要去复制的地点给出来,在下面就相当于根据DOM对象,顺藤摸瓜去复制。

<!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>
    <div class="foo">Hello</div>
    <button class="btn">Copy</button>
    <div class="foo">World</div>

    <script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    <script>
      const btn = document.getElementsByClassName('btn')[0];
      const clipboard = new ClipboardJS(btn, {
        target: function () {
          return document.getElementsByClassName('foo')[1];
        },
      });
    </script>
  </body>
</html>

1.3 通过给复制按钮添加自定义属性来复制内容

<!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>
    <span id="foo">1 + 1 = 2</span>
    <button class="btn" data-clipboard-action="copy" data-clipboard-target="#foo">Copy</button>

    <script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
    <script>
      const btn = document.getElementsByClassName('btn')[0];
      const clipboard = new ClipboardJS(btn);
    </script>
  </body>
</html>

参数说明:

  • data-clipboard-action:剪切板行为,如复制copy,剪切cut
  • data-clipboard-target:剪切板行为的目标

不过,这个样子的复制相当于自动帮你选择,并且帮你按CTRL+C, 复制之后,复制的内容会变蓝

2. 通过document.execCommand()方法

只能说是换汤不换药。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <input type="text" id="copy-input" value="Hello World!" />
    <button id="copy-btn">复制</button>

    <script>
      const copyInput = document.getElementById('copy-input');
      const copyBtn = document.getElementById('copy-btn');

      copyBtn.addEventListener('click', function () {
        copyInput.select();
        document.execCommand('copy');
      });
    </script>
  </body>
</html>

无法执行document.execCommand('paste')方法。

image-20211208210003809

新版本Chrome执行document.execCommand('paste')会返回false,因为读取剪切板涉及用户隐私安全,所以一定要在用户允许的情况下才可以进行操作。

3. 异步Clipboard API

它的所有操作都是异步的,返回Promise对象,而且,它可以将任意内容(比如图片)放入剪切板。

首先,通过navigator.clipboard 返回Clipboard对象,所有操作都是通过这个对象进行的。

const clipboardObj = navigator.clipboard;

Chrome浏览器规定,只有HTTPS协议的页面才能使用这个API。不过,localhost允许使用非加密协议。

3.1 Clipboard.readText()、Clipboard.writeText()

Clipboard.writeText()用于复制文本数据,Clipboard.readText()用于读取剪切板中的文本数据

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <input type="text" placeholder="请输入要复制的内容" id="copy-ipt" />
    <button id="copy-btn">复制</button>
    <br />
    <input type="text" placeholder="会输出复制的内容的内容" id="paste-ipt" />
    <button id="paste-btn">粘贴</button>
    <script>
      const copyIpt = document.getElementById('copy-ipt');
      const copyBtn = document.getElementById('copy-btn');
      const pasteIpt = document.getElementById('paste-ipt');
      const pasteBtn = document.getElementById('paste-btn');

      copyBtn.addEventListener('click', async e => {
        await navigator.clipboard.writeText(copyIpt.value);
      });

      pasteBtn.addEventListener('click', async e => {
        pasteIpt.value = await navigator.clipboard.readText();
      });
    </script>
  </body>
</html>

复制不需要用户给权限, 不过,点击粘贴按钮时,更准确来说是,使用clipboard.readText()方法时,浏览器会弹出一个对话框,询问是否允许读取剪切板。如果禁止,那么就会报错,可以通过try...catch结构处理报错。

image-20211208212459449

3.2 Clipboard.read()、Clipboard.write()

有点像上面两个的加强版,可以复制和粘贴任意数据,如图片

  • Clipboard.read():从剪切板读取数据(如图片)
  • Clipboard.write():写入任意数据到剪切板

Clipboard.write()

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      img {
        width: 200px;
      }
      button {
        margin-left: 70px;
      }
    </style>
  </head>
  <body>
    <img src="https://raw.githubusercontent.com/13535944743/CLZ_img/master/imsges/202112082214161.png" alt="" />
    <br />
    <button id="copyImg-btn">复制图片</button>
    <script>
      const mycopy = async () => {
        const imgURL = 'https://raw.githubusercontent.com/13535944743/CLZ_img/master/imsges/202112082214161.png';
        const data = await fetch(imgURL); //  fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源
        console.log(data);
        const blob = await data.blob(); // Blob 对象表示一个不可变、原始数据的类文件对象。
        // 它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作
        console.log(blob);

        await navigator.clipboard.write([
          new ClipboardItem({
            [blob.type]: blob,
          }),
        ]);
        alert('图片已复制');
      };
      document.getElementById('copyImg-btn').addEventListener('click', mycopy);
    </script>
  </body>
</html>

复制成功后,去到能粘贴图片的地方,如Word、WPS等粘贴,即可看到复制的图片。

Clipboard.read()

const mypaste = async () => {
  const clipboardItems = await navigator.clipboard.read();
  /* 该方法返回一个Promise对象,一旦对象的状态变为resolved,
   * 就可以得到一个数组,每个对象都是ClipboardItem对象的实例
   */
  for (const clipboardItem of clipboardItems) {
    for (const type of clipboardItem.types) {
      const blob = await clipboardItem.getType(type); // 得到blob对象
      document.getElementById('img').src = URL.createObjectURL(blob); // URL.createObjectURL()方法通过blob对象生成一个对应的url
    }
  }
};
document.getElementById('pasteImg-btn').addEventListener('click', mypaste);

复制粘贴的完整代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      img {
        width: 200px;
      }

      button {
        margin-left: 70px;
      }
    </style>
  </head>

  <body>
    <img src="https://raw.githubusercontent.com/13535944743/CLZ_img/master/imsges/202112082214161.png" alt="" />
    <br />
    <button id="copyImg-btn">复制图片</button>
    <br />
    <button id="pasteImg-btn">粘贴图片</button>
    <br />
    <img src="" alt="" id="img" />
    <canvas id="canvas"></canvas>
    <script>
      const mycopy = async () => {
        const imgURL = 'https://raw.githubusercontent.com/13535944743/CLZ_img/master/imsges/202112082214161.png';
        const data = await fetch(imgURL); //  fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源
        console.log(data);
        const blob = await data.blob(); // Blob 对象表示一个不可变、原始数据的类文件对象。
        // 它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作
        console.log(blob);

        await navigator.clipboard.write([
          new ClipboardItem({
            [blob.type]: blob,
          }),
        ]);
        alert('图片已复制');
      };
      document.getElementById('copyImg-btn').addEventListener('click', mycopy);

      const mypaste = async () => {
        const clipboardItems = await navigator.clipboard.read();
        /* 该方法返回一个Promise对象,一旦对象的状态变为resolved,
         * 就可以得到一个数组,每个对象都是ClipboardItem对象的实例
         */
        for (const clipboardItem of clipboardItems) {
          for (const type of clipboardItem.types) {
            const blob = await clipboardItem.getType(type); // 得到blob对象
            document.getElementById('img').src = URL.createObjectURL(blob); // URL.createObjectURL()方法通过blob对象生成一个对应的url
          }
        }
      };
      document.getElementById('pasteImg-btn').addEventListener('click', mypaste);
    </script>
  </body>
</html>

效果:

image-20211209004028815

学习链接:剪贴板操作 Clipboard API 教程 - 阮一峰的网络日志 (ruanyifeng.com)

目录
相关文章
|
6月前
|
前端开发 JavaScript 数据处理
在JavaScript中,异步函数是指那些不会立即执行完毕,而是会在未来的某个时间点(比如某个操作完成后,或者某个事件触发后)才完成其执行的函数
【6月更文挑战第15天】JavaScript中的异步函数用于处理非同步任务,如网络请求或定时操作。它们使用回调、Promise或async/await。
59 7
|
6月前
|
JSON 前端开发 JavaScript
在JavaScript中,异步编程是一种处理非阻塞操作(如网络请求、文件读写等)的重要技术
【6月更文挑战第12天】JavaScript中的异步编程通过Promise和async/await处理非阻塞操作。Promise管理异步操作的三种状态,防止回调地狱,支持链式调用和并行处理。async/await是ES8引入的语法糖,使异步代码更像同步代码,提高可读性。两者结合使用能更高效地处理复杂异步场景。
42 3
|
6月前
|
JavaScript 前端开发 UED
JavaScript基础-DOM操作:查找、创建、修改
【6月更文挑战第12天】本文介绍了DOM基础,包括查找元素(getElementById、getElementsByClassName等)、创建新节点(createElement、createTextNode)和修改节点(innerText、innerHTML、setAttribute等)。强调了易错点,如ID唯一性、性能考量和安全问题,并提供了代码示例。熟练掌握DOM操作对前端开发至关重要,但应注意性能优化,适时使用框架或库。
73 2
JavaScript基础-DOM操作:查找、创建、修改
|
5月前
|
JavaScript 前端开发 索引
JavaScript编码之路 【JavaScript之操作数组、字符串方法汇总】(三)
JavaScript编码之路 【JavaScript之操作数组、字符串方法汇总】(三)
49 1
|
5月前
|
存储 JavaScript 前端开发
js/javascript 操作字符串【全】(含常用的操作字符串的lodash)
js/javascript 操作字符串【全】(含常用的操作字符串的lodash)
51 1
|
6月前
|
JavaScript vr&ar 数据库
技术笔记:Js获取当前日期时间及其它操作
技术笔记:Js获取当前日期时间及其它操作
148 1
|
6月前
|
存储 前端开发 JavaScript
回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。
【6月更文挑战第27天】回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。它作为参数传递给其他函数,在特定条件满足或任务完成后被调用。例如,`asyncOperation`函数接受回调函数`handleResult`,模拟异步操作后,调用`handleResult`传递结果。这样,当异步任务完成时,`handleResult`负责处理结果。
43 1
|
6月前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
6月前
|
存储 JavaScript 前端开发
JavaScript中的数组是核心数据结构,用于存储和操作序列数据
【6月更文挑战第22天】JavaScript中的数组是核心数据结构,用于存储和操作序列数据。创建数组可以使用字面量`[]`或`new Array()`。访问元素通过索引,如`myArray[0]`,修改同样如此。常见方法包括:`push()`添加元素至末尾,`pop()`移除末尾元素,`shift()`移除首元素,`unshift()`添加到开头,`join()`连接为字符串,`slice()`提取子数组,`splice()`进行删除、替换,`indexOf()`查找元素位置,`sort()`排序数组。还有其他如`reverse()`、`concat()`等方法。
136 2
|
6月前
|
JavaScript 前端开发 安全
【JavaScript 】DOM操作快速入门
【JavaScript 】DOM操作快速入门
94 2