富文本編輯器小結
近況
最近由於公司業務上的需求,我們需要一個自己的編輯器來編寫我們得到APP裡面的訂閱文章,為什麼需要自己的編輯器,主要是因為用第三方的編輯器很難完成公司定製化的需求,比如:排版上我們想要更好看點,統一,因為各個訂閱專欄編輯的人不一樣,容易造成各種不同的審美差異,解決方案有2種:
採用一個可定製化的第三方富文本編輯器,然後自己寫插件來滿足自己的要求。
自己寫一個富文本編輯器。
最後和團隊的人商量決定,自己擼一個吧,因為使用第一種方案,依賴於別人的開源插件,總是不太放心,而且害怕到時候有什麼問題,要研究他們的源碼,那就跟自己寫差不多多少,而且我們自己擼一個,並非要寫一個非常通用,可以開源的富文本編輯器,我們只需要針對我們自己業務,寫一個定製化符合公司使用的編輯器就行了。綜上,我開始了這次非常愉快(坑爹)的編輯器之旅!!!
先看效果圖,如圖所示,如果有訂閱了我們得到APP裡面專欄文章的,可以對比下,現在和8月的文章就能看出來了。
無處不在的坑
首先web端的富文本編輯器,基本命令參照documen命令文檔,兼容性的問題就不說了,大家都知道,主要說說一些開發了才能知道的坑。
div還是p
可編輯模式下(是否支持可編輯可以用HTMLElement.isContentEditable命令來查看的),如果內部沒有P標籤這個初始化標籤,編寫的時候,換行給你添加的標籤將會是div,如圖所示:
這裡就已經不太符合我們要求了,不想要各種div標籤在文本外面,語義化來說,我們應該用p標籤才對。
解決方案: 初始化添加一個p標籤,並且裡面加入一個br
<p><br></p>刪除也要小心翼翼
這個坑跟第一個同樣的原因,只是表現形式不同,如果你開始刪除你的編輯文本,刪除完之後,整個可編輯元素,就變成空了,意味著,又沒有初始化的p標籤,那麼你在添加文字的時候,就會跟上面的問題一樣了。
解決方案:監聽刪除動作,判斷內部還是否有子元素,沒有初始化p標籤
行內標籤很有個性
添加文本需要的行內標籤,例如: bold,italic,underline,subscript等等,可以任意添加和取消,一般來說沒有任何問題,需要注意的是,你不能隨意更改相關標籤的css特殊樣式,炒個栗子:bold在chrome裡面添加一個b標籤,瀏覽器樣式,font-weight:bolder;,如果你自己css給覆蓋掉,變成 font-weight: normal;,那麼再次點擊,應該取消的時候,不會成功的。原因我沒有找到文檔,據我推測,因為是取消的時候,判斷條件為是否有相關命令的css樣式,並不是單純的文字外部標籤名稱。
formatBlock跟你說,不是所有的牛奶都是特侖蘇!
使用formatBlock來添加或者更換文字的外標籤時,要特別注意--BLOCKQUOTE這個東東,
document.execCommand(formatBlock, false, "<blockquote>"),它能添加或者更換,但是要取消他的時候,就不起作用了。解決方案: 在執行代碼的時候,多加一個判斷,判斷當前選中文字的外標籤是什麼,再決定是需要執行什麼命令。
let Range = document.getSelection().getRangeAt(0),n formatName = Range.commonAncestorContainer.parentElement.nodeName === BLOCKQUOTE ? P : BLOCKQUOTE;ndocument.execCommand(formatBlock, false, formatName)n
removeFormat並不是萬能的
清楚格式這個命令,主要會清除掉附帶在標籤上的內聯樣式,也就是style,但是不會清除class名稱,這意味著,從外部粘貼過來的文本,如果不幸的ClassName和你的css裡面的ClassName重複了,就會帶上你的css樣式。而且也不會清楚裡面內聯元素標籤,什麼意思呢?就是span都還是存在的,從原理上來說這個不影響最後的顯示,但沒有必要需要這些個標籤,很容易產生其他的問題。
解決方案:執行清楚格式操作的時候,多加一些操作,把無用的樣式,標籤和ClassName全部幹掉。(此處必須有殺氣!)
其他
至於其他的很多命令(indent,fontSize,fontColor...),我這裡沒有使用,也不知道是否有坑,原因是前面說到的樣式統一,保證美觀,不支持內聯樣式,由統一的css樣式渲染。
推薦閱讀: