js实现在可编辑的div中粘贴图片

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

前言

在富文本编辑器中粘贴图片是很正常的操作,之前我也实现过简易版的富文本编辑器,今天借着这个机会,重拾旧日知识,手动实现在可编辑的div中粘贴图片。

可编辑的div

div是可以编辑的?

对的你没听错,html5新增了一个属性,contenteditable

这个属性不单单是对div元素有效,而是大部分元素都支持。

  <style>
    div {
      width: 200px;
      height: 200px;
      border: 1px solid red;
    }
  </style>
  <div contenteditable="true">
    hello world!
  </div>
复制代码

效果如下:

GIF 2021-8-12 20-01-24.gif

既然我们div可以编辑了,那么我们接下来看看怎么实现往div中粘贴图片?

paste事件

粘贴图片,我们首先得知道复制的图片的信息,然后再把图片渲染出来。

我们可以先监听paste事件,也就是粘贴事件,在这个事件里去获取复制的图片。

我们先把这个事件的event对象打印出来

    var div = document.querySelector('div')
    div.addEventListener('paste', (e) => {
      console.log(e)
    })
复制代码

如下图:

image.png

这个event对象里面有个clipboardData属性,是一个DataTransfer对象,剪切板的数据都存在这个属性里面。

介绍一下clipboardData对象的几个属性

  • files

    复制的文件的列表,数组类型,如果没有复制到文件,则为空数组。每一项是File对象。

    通过clipboardData数据看到的打印是空的,如果你打印files看到是有值的

    image.png

  • items

    包含复制数据的类型的列表,每一项都有2个值

    • kind

      复制的数据的类型,一般为string或者file

    • type

      复制的数据的MIME-Type类型, 比如image/png, text/plain, text/html

    它的原型链上还有getAsFile()(获取文件对象), getAsString((str) => {})(获取字符串)等方法

  • types

    复制的数据的类型的列表,一般为这几个值:

    • text/plain
    • text/html
    • Files
    • 等等

    这个clipboardData对象的主要api讲完了,咱们试试通过代码来实现获取图片并且实现粘贴图片。

    如果我们想阻止浏览器的默认行为(默认会把图片粘贴),而是通过我们手动粘贴上,我们就要阻止paste事件的默认行为

    通过e.preventDefault()阻止。

    代码如下:

    通过e.clipboardData.files方式

      var div = document.querySelector('div')
      div.addEventListener('paste', (e) => {
        e.preventDefault() // 阻止默认行为
        // 获取files列表
        const files = e.clipboardData.files
        for (let i = 0; i < files.length; i++) {
          const reader = new FileReader()
          reader.onload = (e) => {
            const img = new Image()
            // base64
            img.src = e.target.result
            // 插入到div中
            div.appendChild(img)
          }
          // 使用reader读取file对象
          reader.readAsDataURL(files[i])
        }
      })
    复制代码

    通过e.clipboardData.items方式

      var div = document.querySelector('div')
      div.addEventListener('paste', (e) => {
        e.preventDefault() // 阻止默认行为
        const items = e.clipboardData.items
        for (let i = 0; i < items.length; i++) {
          // 判断是file类型
          if (items[i].kind === 'file') {
            // 获取file对象 
            const file = items[i].getAsFile()
            const reader = new FileReader()
            reader.onload = (e) => {
              const img = new Image()
              // base64
              img.src = e.target.result
              // 插入到div中
              div.appendChild(img)
            }
            // 使用reader读取file对象
            reader.readAsDataURL(file)
          }
        }
      })
    复制代码

    这里的代码只是简单的把剪切板的图片读取渲染的过程,事实上还要兼容很多种情况,比如ctrl+ c复制网页的图片该如何渲染,如何把复制大段的文本提取出img元素等等。

总结

以上就是我总结的js实现在可编辑的div中粘贴图片。

这篇文章是想让大家学习到paste事件,和clipboardData对象,然后实现简易的复制粘贴图片。

感谢你们的阅读。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享