前端粘贴复制还能这样玩

365 阅读1分钟

今天无意间发现了一个神奇的事件paste, 下面来介绍一下吧。

为了测试粘贴复制,下面我们先来写一个点击复制的工具函数

    const clipboard = (text) => {
      return new Promise((resolve, reject) => {
        // 创建隐藏的 Textarea 标签,并将文本放入其中
        let textarea = document.createElement('textarea')

        textarea.style.position = 'absolute'
        textarea.style.top = '0'
        textarea.style.left = '0'
        textarea.style.border = 'none'
        textarea.style.margin = '0'
        textarea.style.padding = '0'
        textarea.style.opacity = '0'
        textarea.value = text

        document.body.appendChild(textarea)

        // 复制 Textarea 标签的文本
        textarea.select()
        document.execCommand('copy')

        // 移除 Textarea 标签
        document.body.removeChild(textarea)

        resolve()
      })
    }

paste事件:当用户在浏览器用户界面发起“粘贴”操作时,会触发 paste 事件。

这个只会作用于可输入文本的dom元素上。如果都不可输入,那么我们整个页面也是可以触发的。

下面来看一下例子。

    <!DOCTYPE html>
    <!-- 即使给html设置了contenteditable设置了false,依旧是可以触发paste事件的-->
    <html lang="en" contenteditable="false">
    <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>页面中没有可以可输入文本的dom元素</div>
      <script>
        document.addEventListener("paste", function(e) {
          console.log("e", e)
        })
      </script>
    </body>
    </html>

image.png 下面我们让div变成可以输入文本的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>
      <style>
        div {
          width: 300px;
          height: 300px;
          background: skyblue;
        }
      </style>
    </head>
    <body>
      <div contenteditable="true">
        我是可输入文本的div
      </div>
      <script>
        const div = document.getElementsByTagName("div")[0]

        // 这个事件只作用于可编辑的dom元素上。
        // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。
        div.addEventListener("paste", function(e) {
            console.log("e", e)
        })
      </script>
    </body>
    </html>

paste测试.gif 上面可以看出,只有光标聚焦到div元素上时执行粘贴行为时,才会触发paste事件。

开始的时候我只是想获取剪切板中粘贴的图片对象。就像掘金编辑器一样,平常就是在别的地方拷贝图片到文章中。

我们可以这样获取粘贴的图片对象。然后就可以上传到服务器了。

    <!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>
      <style>
        div {
          width: 300px;
          height: 300px;
          background: skyblue;
        }
      </style>
    </head>
    <body>
      <div contenteditable="true">
        我是可输入文本的div
      </div>
      <script>

        const div = document.getElementsByTagName("div")[0]

        // 这个事件只作用于可编辑的dom元素上。
        // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。
        div.addEventListener("paste", function(e) {
          // 明明打印e.clipboardData.item没有值,但是最后获取getAsFile时,就可以打印出来。
          console.log("e:获取文件对象",e.clipboardData.items[0].getAsFile() )
        })
      </script>
    </body>
    </html>

paste测试获取文件对象.gif

那么获取文件对象会了,那么如何获取普通的复制的文本呢?

事件处理程序可以通过调用事件的 clipboardData 属性上的 getData()访问剪贴板内容。

<!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>
  <style>
    div {
      width: 300px;
      height: 300px;
      background: skyblue;
    }
  </style>
</head>
<body>
  <div contenteditable="true">
    我是可输入文本的div
  </div>

  <p>点我复制</p>
  <script>

    const clipboard = (text) => {
      return new Promise((resolve, reject) => {
        // 创建隐藏的 Textarea 标签,并将文本放入其中
        let textarea = document.createElement('textarea')

        textarea.style.position = 'absolute'
        textarea.style.top = '0'
        textarea.style.left = '0'
        textarea.style.border = 'none'
        textarea.style.margin = '0'
        textarea.style.padding = '0'
        textarea.style.opacity = '0'
        textarea.value = text

        document.body.appendChild(textarea)

        // 复制 Textarea 标签的文本
        textarea.select()
        document.execCommand('copy')

        // 移除 Textarea 标签
        document.body.removeChild(textarea)

        resolve()
      })
    }

    const div = document.getElementsByTagName("div")[0]
    const p = document.getElementsByTagName("p")[0]


    // 这个事件只作用于可编辑的dom元素上。
    // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。
    div.addEventListener("paste", function(e) {
      // 获取剪切板中的文本内容
      console.log("e: 获取文本",e.clipboardData.getData("text"))
    })

    
    // 点击div复制div中的内容到剪贴板
    p.addEventListener("click", function() {clipboard(p.innerText)})
  </script>
</body>
</html>

paste测试获取普通文本.gif

到此就结束啦,如果就得学到啦,就给一个小小的star,谢您们~