Clipboard 剪贴板学习笔记

Posted 胖鹅68

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clipboard 剪贴板学习笔记相关的知识,希望对你有一定的参考价值。

文章目录

一、参考

  1. 剪贴板操作 Clipboard API 教程 阮一峰
  2. ClipboardItem MDN

二、内置对象

2.1 Clipboard

  1. Clipboard 接口实现了 Clipboard API,如果用户授予了相应的权限,其就能提供系统剪贴板的读写访问能力。
  2. 在 Web 应用程序中,Clipboard API 可用于实现剪切、复制和粘贴功能。
  3. 此项功能仅在一些支持的浏览器的安全上下文(HTTPS)中可用

2.2 ClipboardEvent

ClipboardEvent 接口描述了与修改剪切板相关信息的事件,这些事件包括 剪切cut , 复制copy 和 粘贴paste 事件

2.3 ClipboardItem

ClipboardItem 接口是对剪切板里的内容的抽象,比如我们选中网页上的一段文字,并右击选择复制,这样复制的内容就作为一个 ClipboardItem 存在

三、安全限制

3.1 风险

由于用户可能把敏感数据(比如密码)放在剪贴板,允许脚本任意读取会产生安全风险,所以这个 API 的安全限制比较多。

3.2 策略

  • 首先,Chrome 浏览器规定,只有 HTTPS 协议的页面才能使用这个 API。不过,开发环境(localhost)允许使用非加密协议。
  • 其次,调用时需要明确获得用户的许可

3.3 两个权限:

  • clipboard-write(写权限)"写权限"自动授予脚本
  • clipboard-read(读权限),而"读权限"必须用户明确同意给予。
  • 也就是说,写入剪贴板,脚本可以自动完成,但是读取剪贴板时,浏览器会弹出一个对话框,询问用户是否同意读取。

四、API

  • navigator.clipboard.readText();
    Clipboard.readText()方法用于复制剪贴板里面的文本数据。

  • navigator.clipboard.read();
    Clipboard.read()方法用于复制剪贴板里面的数据,可以是文本数据,也可以是二进制数据(比如图片)。该方法需要用户明确给予许可。

  • navigator.clipboard.writeText(‘Yo’)
    Clipboard.writeText()方法用于将文本内容写入剪贴板。

  • navigator.clipboard.write
    Clipboard.write()方法用于将任意数据写入剪贴板,可以是文本数据,也可以是二进制数据。

navigator.clipboard.write([
  new ClipboardItem(
    [blob.type]: blob
  )
])

4.1 综合案例

<!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>
  <style>
    ul li 
      cursor: pointer;
      color: blue;
      line-height: 36px;
    
  </style>
  <body>
    <ul>
      <li onclick="getClipboardContents()">读取剪贴板内容 navigator.clipboard.readText()</li>
      <li onclick="getClipboardContentsImg()">读取剪贴板内容二进制、图片 navigator.clipboard.read()</li>
      <li onclick="copyPageUrl()">Clipboard.writeText()方法用于将文本内容写入剪贴板。</li>
      <li onclick="copyImg()">Clipboard.write() 方法用于将(二进制、图片、文本)内容写入剪贴板。</li>
      <li onclick="copyBothImgText()">Clipboard.write() 同时将图片和文字写入到剪贴板中</li>
      <input type="text" />
      <img src="" id="img" alt="">
    </ul>
  </body>
  <script>
    async function getClipboardContents() 
      try 
        const text = await navigator.clipboard.readText();
        console.log('Pasted content: ', text);
        alert(text)
       catch (err) 
        console.error('Failed to read clipboard contents: ', err);
      
    

    // 读取剪贴板中的二进制文件
    async function getClipboardContentsImg() 
      try 
        const clipboardItems = await navigator.clipboard.read();
        console.log(clipboardItems);
        for (const clipboardItem of clipboardItems) 
          // ClipboardItem.types属性返回一个数组,里面的成员是该剪贴项可用的 MIME 类型,比如某个剪贴项可以用 HTML 格式粘贴,也可以用纯文本格式粘贴,那么它就有两个 MIME 类型(text/html和text/plain)。
          for (const type of clipboardItem.types) 
            if (type !== "image/png")  // 判断是否是图片,如果不是图片,不做后面的处理
              return
            
            // ClipboardItem.getType(type)方法用于读取剪贴项的数据,返回一个 Promise 对象。该方法接受剪贴项的 MIME 类型作为参数,返回该类型的数据,该参数是必需的,否则会报错。
            const blob = await clipboardItem.getType(type);
            const urlStr = URL.createObjectURL(blob)
            console.log(urlStr);
            document.getElementById('img').src = urlStr; // URL.createObjectURL()方法通过blob对象生成一个对应的url
          
        
       catch (err) 
        console.error(err.name, err.message);
      
    

    // 将文本写入到剪贴板
    async function copyPageUrl() 
      try 
        await navigator.clipboard.writeText(location.href);
        console.log('Page URL copied to clipboard');
       catch (err) 
        console.error('Failed to copy: ', err);
      
    

    // 将 图片 写入到剪贴板
    async function copyImg() 
      try 
        const imgURL = 'https://dummyimage.com/300.png';
        const data = await fetch(imgURL);
        const blob = await data.blob();
        await navigator.clipboard.write([
          new ClipboardItem(
            [blob.type]: blob,
          ),
        ]);
        console.log('Image copied.');
       catch (err) 
        console.error(err.name, err.message);
      
    

    // 同时将图片和文字放到剪贴板中
    async function copyBothImgText() 
      // const image = await fetch('a.png');
      const image = await fetch('https://dummyimage.com/300.png');
      const blob = await image.blob();
      const text = new Blob(['Cute sleeping kitten'],  type: 'text/plain' );
      const item = new ClipboardItem(
        'text/plain': text,
        [blob.type]: blob,
      );
      await navigator.clipboard.write([item]);
    
  </script>
</html>

五、事件

  • Element: copy
    用户向剪贴板放入数据时,将触发copy事件。

  • Element: cut

  • Element: paste
    用户使用剪贴板数据,进行粘贴操作时,会触发paste事件。

  • Window: clipboardchange

5.1 案例

// 用户使用剪贴板数据,进行粘贴操作时,会触发paste事件。
    document.addEventListener('paste', async (e) => 
      console.log(e);
      debugger;
      e.preventDefault();
      const text = await navigator.clipboard.readText();
      console.log('Pasted text: ', text);
    );

    // 用户向剪贴板放入数据时,将触发copy事件。
    document.addEventListener('copy', async (e) => 
      console.log(e);
      debugger;
      e.preventDefault();
      try 
        let clipboardItems = [];
        for (const item of e.clipboardData.items) 
          if (!item.type.startsWith('image/')) 
            continue;
          
          clipboardItems.push(
            new ClipboardItem(
              [item.type]: item,
            )
          );
          await navigator.clipboard.write(clipboardItems);
          console.log('Image copied.');
        
       catch (err) 
        console.error(err.name, err.message);
      
    );

以上是关于Clipboard 剪贴板学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

阮一峰老师JavaScript课程学习笔记

阮一峰:jQuery官方基础教程笔记

Android——ClipBoard(复制和粘贴)

Android——ClipBoard(复制和粘贴)

语法》第六章 数组

javascipt继承机制(from阮一峰)