之前用vue开发一个聊天软件,用pre contenteditable="true"作为输入框。粘贴的时候,会把其他html元素粘贴进来,这样css样式完全乱了。
于是写了这个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
window.addEventListener('paste', function (e) {
const clipboardData = e.clipboardData
if (clipboardData && clipboardData.items) {
e.preventDefault()
const reg = /<\/?(?!\/img|img|a|\/a)(.|\n|\r)*?>/g
const reg1 = /<(img|a).*?(src|class)\s*=\s*['|"].*?['|"].*?>/g
clipboardData.items.forEach(item => {
if (item.kind === 'string') {
item.getAsString((str) => {
if (window.getSelection && str !== '' && str !== null) {
str = str.replace(reg, '')
let arr = null
const flag = document.createDocumentFragment()
let index = 0
while ((arr = reg1.exec(str)) != null) {
const textNode = document.createTextNode(str.slice(index, arr.index))
const imgNode = document.createElement('img')
const src = arr[0].match(/src\s*=\s*['|"](.*?)['|"]/)
const className = arr[0].match(/class\s*=\s*['|"](.*?)['|"]/)
if (src) {
imgNode.src = src[1]
}
if (className) {
imgNode.className = className[1]
}
flag.appendChild(textNode)
flag.appendChild(imgNode)
index = arr.index + arr[0].length
}
if (str.length !== index) {
const textNode = document.createTextNode(str.slice(index))
flag.appendChild(textNode)
}
const sel = window.getSelection()
const range = sel.getRangeAt(0)
range.deleteContents()
range.insertNode(flag)
range.collapse(false)
}
})
} else if (item.kind === 'file') {
const pasteFile = item.getAsFile()
// eslint-disable-next-line no-console
console.log(pasteFile)
}
})
}
})
具体思路是监听粘贴事件,通过正则把html标签去掉,只保留img标签。
虽然项目上没有用到这段代码,也是费了好多时间,记录一下。