这是我参与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>
复制代码
效果如下:
既然我们div可以编辑了,那么我们接下来看看怎么实现往div中粘贴图片?
paste事件
粘贴图片,我们首先得知道复制的图片的信息,然后再把图片渲染出来。
我们可以先监听paste
事件,也就是粘贴事件,在这个事件里去获取复制的图片。
我们先把这个事件的event对象打印出来
var div = document.querySelector('div')
div.addEventListener('paste', (e) => {
console.log(e)
})
复制代码
如下图:
这个event对象里面有个clipboardData
属性,是一个DataTransfer对象,剪切板的数据都存在这个属性里面。
介绍一下clipboardData
对象的几个属性
-
files
复制的文件的列表,数组类型,如果没有复制到文件,则为空数组。每一项是
File
对象。通过clipboardData数据看到的打印是空的,如果你打印files看到是有值的
-
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
对象,然后实现简易的复制粘贴图片。
感谢你们的阅读。