直接上代码:我使用的是vue框架
html部分:
<div class="editable" contenteditable="true" ref="inputBox" @click="handleBoxClick" ></div>
<button @click="addImg">测试加图片</button>
对onselectionchange进行监听
// onselectionchange仅存在于document
document.onselectionchange = () => {
let selection = document.getSelection();
if (selection.rangeCount > 0) {
//rangeCount是Selection的属性,它表示Selection正在应用的Range数目
const range = selection.getRangeAt(0);
// commonAncestorContainer是Range的属性,它表示Range的两个边界点的距离最近的共同父元素
if (this.$refs.inputBox.contains(range.commonAncestorContainer)) {
this.rangeOfInputBox = range;
}
}
};
添加图片/表情:
addImg(e) {
let emojiEl = document.createElement("img");
emojiEl.src = "./lib/image/higher-quality1.png";
emojiEl.width = "50";
if (!this.rangeOfInputBox) {
this.rangeOfInputBox = new Range();
// selectNodeContents(node)是Range的方法,将一个Range设定为选中整个node元素内容。
this.rangeOfInputBox.selectNodeContents(this.$refs.inputBox);
}
if (this.rangeOfInputBox.collapsed) {
// insertNode(node)是Range的方法,可以将node元素插入到Range的起始边界点。
this.rangeOfInputBox.insertNode(emojiEl);
} else {
this.rangeOfInputBox.deleteContents();
this.rangeOfInputBox.insertNode(emojiEl);
}
this.rangeOfInputBox.collapse(false);
},
handleBoxClick(event) {
let target = event.target;
if (target.tagName.toLowerCase() === "img") {
let range = new Range();
// setStartBefore(node)是Range的方法,可以设定边界起始点的位置到一个元素之前
range.setStartBefore(target);
range.collapse(true);
document.getSelection().removeAllRanges();
document.getSelection().addRange(range);
}
},