• Click To Copy 的实现 [2/2] JavaScript实现复制内容到前切板


    在过去的几年,浏览器都一般使用document.execCommand来进行剪切板操作。诚然,有这样一个单独且被广泛支持的方式去完整的复制和粘贴内容到Web应用是很帮的,但是,这种方式是有一定代价的:剪切板访问是同步的,并且,由于通常是操作用于input元素,因此只能进行DOM的读写操作。

    这些问题,如果是在复制粘贴少量字节的文本内容时,同步访问是不会有多大影响的。但是同步访问会导致在很多情况下造成页面阻塞。在内容被安全粘贴之前,还需要时间去净化,解码。如果浏览器需要加载自粘贴内容的外链资源,那么有可能会因为磁盘读取和网络问题带来页面阻塞。试想,如果混入权限,询问用户能否在访问剪切板的时候阻塞页面会怎么样呢?

    同时,在使用document.execCommand进行剪切板访问操作的时候,交互的权限定义是非常松散的,并且会因为浏览器的不同有所区别。因此,想象,如果专用的剪切板API解决了页面阻塞和权限问题会是什么样呢?

    这就是 Async Clipboard API,(异步前切板API),该方案在Chrome66中被退出,提供了很好的权限模型定义,并且由于异步特点不会阻塞页面。

    复制:写入文本至剪切板(Copy: writing text to the clipboard)

    通过调用writeText()可以实现复制文本到剪切板,由于该API是异步执行的,writeText()方法会返回一个Promise用于处理resolved或者rejected,这取决于传入的文本是否被正常传入。

    navigator.clipboard.writeText('Text to be copied')
      .then(() => {
        console.log('Text copied to clipboard');
      })
      .catch(err => {
        // This can happen if the user denies clipboard permissions:
        console.error('Could not copy text: ', err);
      });
    

    类似的,你可以将该过程写做一个异步函数( async function

    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);
      }
    }
    

    粘贴:从剪切板读出文本(Paste:reading)

    这个过程和复制很想,你可以通过调用readText()来剪切剪切板中的文本。并且等待返回的Promise来resolve,或者reject。

    navigator.clipboard.readText()
      .then(text => {
        console.log('Pasted content: ', text);
      })
      .catch(err => {
        console.error('Failed to read clipboard contents: ', err);
      });
    

    为了保持一致,这是等效的异步函数:

    async function getClipboardContents() {
      try {
        const text = await navigator.clipboard.readText();
        console.log('Pasted content: ', text);
      } catch (err) {
        console.error('Failed to read clipboard contents: ', err);
      }
    }
    

    处理粘贴事件(Handling paste events)

    已经计划引入一个新事件来检测剪贴板的变化,但是目前最好使用“粘贴”事件。 它与用于读取剪贴板文本的新异步方法很好地结合在一起:

    document.addEventListener('paste', event => {
      event.preventDefault();
      navigator.clipboard.readText().then(text => {
        console.log('Pasted text: ', text);
      });
    });
    

    安全和权限(Security and permissions)

    剪贴板访问一直是浏览器的安全隐患。没有适当的权限,页面可以静默的复制所有的恶意内容到用户的剪切板,在用户粘贴的时候,将产生灾难性的结果。想象一个网页静默的复制 rm -rf / 或者减压炸弹图片(decompression bomb image)到你的剪切板。

    让网页不受限制地访问剪贴板就更麻烦了。

    用户通常会将密码和个人信息等敏感信息复制到剪贴板上,这样任何页面都可以在用户不知情的情况下读取这些信息。

    和很多新的API一样,navigator.clipboard仅仅支持通过HTTPS协议部署的页面,这样能够有效阻止滥用,仅当页面是活动选项卡时才允许剪贴板访问,处于活动选项卡中的页面可以在不请求权限的情况下写入剪贴板,但从剪贴板读取始终需要权限。

    为了使事情变得简单,将两个新的复制和粘贴权限添加到了权限API(Permissions API

    当页面为活动选项卡时,将自动向页面授予剪贴板写入权限。 必须请求剪贴板读取权限,您可以通过尝试从剪贴板读取数据来完成。

    { name: 'clipboard-read' }
    { name: 'clipboard-write' }
    

    与使用Permissions API进行的所有操作一样,可以检查您的应用是否具有与剪贴板进行交互的权限:

    navigator.permissions.query({
      name: 'clipboard-read'
    }).then(permissionStatus => {
      // Will be 'granted', 'denied' or 'prompt':
      console.log(permissionStatus.state);
    
      // Listen for changes to the permission state
      permissionStatus.onchange = () => {
        console.log(permissionStatus.state);
      };
    });
    

    向后看(Looking back)

    在介绍Async Clipboard API之前,各浏览器有一些不同的复制粘贴操作的混合实现。

    在大多数浏览器中,浏览器自身的复制粘贴能够通过使用document.execCommand('copy')document.execCommad('paste')来触发,如果被复制的文本是一个不在DOM中的字符串。我必须注入并选择它:参考[Click To Copy 的实现 [1/2] JavaScript实现复制内容到前切板]

    检测和备用方案(Detection and fallback)

    检测浏览器是否支持Async Clipboard API 操作 paste,如果不支持则采用替代方案,以防止报错。

    document.addEventListener('paste', async e => {
      let text;
      if (navigator.clipboard) {
        text = await navigator.clipboard.readText()
      }
      else {
        text = e.clipboardData.getData('text/plain');
      }
      console.log('Got pasted text: ', text);
    });
    

    阅读原文

  • 相关阅读:
    asp.net mvc Bundle
    Nginx配置文件详细说明
    Nginx 负载均衡配置和策略
    WPF 体系结构
    理解WPF中的视觉树和逻辑树
    物料需求預估
    缓存ViewState减少网络传输
    xingfu
    如何在表格中插入图片
    add
  • 原文地址:https://www.cnblogs.com/jaycethanks/p/13473981.html
Copyright © 2020-2023  润新知