文章原文: https://www.cnblogs.com/yalong/p/11883585.html
演示效果如下:

具體代碼可以看 https://github.com/YalongYan/edit-by-contenteditable , 下面分析實現的大概過程
代碼實現過程
1.把div容器變成可編輯的,用 contenteditable="true"
2.div容器里面的內容都用 v-html
渲染
3.輸入 #
出現下拉選擇,監聽 keyup
事件即可
4.下拉框的位置,即 left
值 通過查詢容器里面的內容計算出來(要區分漢字,字母的寬度)
5.按上下按鈕,下拉框數據也移動,通過給document 添加keydown事件,但是記得在組件銷毀的時候,把事件去掉,代碼如下:
created () { // 全局監聽鍵盤事件
document.addEventListener("keydown", this.documentKeyMethod)
},
beforeDestroy () { // 組件銷毀之前 把全局的事件解除了
document.removeEventListener("keydown", this.documentKeyMethod)
}
6.每次在容器里點擊,或者按左右鍵的時候,記錄下光標位置(lastSelection
是全局變量)
let selection = window.getSelection ? window.getSelection() : document.selection
let range = selection.createRange ? selection.createRange() : selection.getRangeAt(0)
lastSelection = selection
7.把選中的數據回顯到容器里面,只需給光標處插入節點即可
8.插入節點后,光標自動插入到新數據的后面
lastSelection.collapse(childNode, index)
-
在藍色數據里面輸入內容的時候,需要把這個數據直接刪除,但是如果用戶就是想在后面輸入內容的話就需要特殊處理了,第十條為解決辦法
10.在藍色數據的直接后面(沒有空格)輸入內容的時候,需要讓光標自動往后移動一位,監聽kedDown
事件即可,移動光標的時候需要判斷后面是否有空格,沒有的話還的插入一個空格
遇到的問題
1.必須加上這個 user-select: none
,不加的話,點擊下拉框的時候,會導selection變化,無法記錄在contenteditable="true"
div里面的位置, 兼容寫法如下:
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none;
2.需要設置字體,不然有些瀏覽器(比如uc瀏覽器)空格寬度不一致,我設置的字體css如下:
.editContentCtn{
// 不設置字體的話 空格的寬度會很寬
font-family: 'Avenir', 'Helvetica', 'Arial', 'sans-serif';
}
代碼地址:
https://github.com/YalongYan/edit-by-contenteditable
參考鏈接:
https://segmentfault.com/a/1190000005869372
http://cn.voidcc.com/question/p-dchxjkvr-ye.html