pasteImg
by imys
HTML
<div id="app">
<div contenteditable class="paste-accept" ref="accept" @paste="onPaste"></div>
<textarea @keydown="onKeydown" ref="input" v-model="pasteImg"></textarea>
<div v-if="pasteImg"><img :src="pasteImg"></div>
</div>
CSS
.paste-accept {
position: fixed;
top: -100px;
width: 1px;
height: 1px;
opacity: 0;
overflow: hidden;
}
textarea {
width: 500px;
height: 100px;
border: 1px solid #ddd;
overflow: hidden;
}
JavaScript
// paste.js 对 safari 图片粘贴兼容的实现
// 注:contentediable 图片粘贴在 safari 不存在兼容问题,只是针对 textarea
// 原理:通过 Keydown(粘贴是在keyup后才发生) 监听 Ctrl+v,设置隐藏的 contenteditable 元素获取焦点来接受图片复制
new Vue({
el: '#app',
data: {
pasteImg: ''
},
methods: {
onKeydown(e) {
// hook Ctrl+v
if(e.ctrlKey && e.keyCode === 86) {
console.log('hook Ctrl+v')
this.$refs.accept.focus()
}
},
onPaste(e) {
const evt = e.originalEvent || e
const clipboard = evt.clipboardData
if (clipboard.items) {
// 正常处理
const item = clipboard.items[0]
const url = window.URL.createObjectURL(item.getAsFile())
this.showPaste(url)
return
}
// 以下用于兼容 safari,safari 会直接生成一个 img 元素
const img = e.target.querySelector('img')
if(!img) return
this.showPaste(img.src)
img.remove()
},
showPaste(url) {
this.pasteImg = url
this.$nextTick(() => {
this.$refs.input.focus()
})
}
}
})