自己打造HTML在線編輯器的實(shí)現(xiàn)難點(diǎn)分析
HTML在線編輯器實(shí)際上是什么
其實(shí)有好幾種實(shí)現(xiàn)方式,目前用得最多、兼容性最好的還是iframe方式。
<iframe src="" frameborder="0"></iframe>
只有這個(gè)空iframe是不行的,還要用Javascript把它設(shè)成可編輯:
iframe.contentWindow.document.designMode = "on";
iframe.contentWindow.document.contentEditable = true;
換而言之,HTML在線編輯器就是一個(gè)可編輯的iframe。
加粗、斜體、下劃線、加鏈接等功能如何實(shí)現(xiàn)
瀏覽器已經(jīng)提供了實(shí)現(xiàn)這些功能的接口execCommand:
iframe.contentWindow.document.execCommand(cmd, isDefaultShowUI, value);
這三個(gè)參數(shù)的意思分別是:
- cmd:命令文本,有好多,IE的可以看這里,F(xiàn)irefox的可以看這里。
- isDefaultShowUI:是否默認(rèn)顯示交互界面,比如加鏈接的時(shí)候,可以通過(guò)界面填入鏈接。不過(guò)這個(gè)參數(shù)存在兼容性問(wèn)題,一般設(shè)為false將其禁用,并另外制作交互界面。
- value:傳入的值,某些命令可以省略。
execCommand的問(wèn)題是,生成的代碼可能不標(biāo)準(zhǔn),比如在IE下,文字加粗用的是b標(biāo)簽而不是strong標(biāo)簽。
交互問(wèn)題
用戶不可能總是在編輯器中輸入,比如加粗、插入圖片等功能是通過(guò)按鈕操作的。假設(shè)用戶要加粗一段選中的文字,當(dāng)他按了加粗按鈕后,選區(qū)以及焦點(diǎn)也會(huì)跟著跑到那去,因此選區(qū)(選中的文字)丟失,操作也就無(wú)法完成;同理,插入圖片時(shí)插入位置也會(huì)丟失。
也就是說(shuō),要保存最后出現(xiàn)在編輯器中的選區(qū)。我采取的方案是,當(dāng)焦點(diǎn)在編輯器內(nèi)的時(shí)候,用一個(gè)定時(shí)器(setInterval)定時(shí)獲取當(dāng)前選區(qū)。選區(qū)編程平時(shí)很少用,做起來(lái)也有很多兼容性問(wèn)題,主要是參考微軟的MSDN(TextRange ControlRange)和Mozilla的MDC(Range Selection)了。
回車問(wèn)題
在IE下,按回車是換段落,生成<p>,但在Firefox下是換行,生成的是<br>。要解決這個(gè)問(wèn)題,就要監(jiān)聽(tīng)keydown事件,如果檢測(cè)到按鍵是回車,就插入“<p></p>”。
獲取標(biāo)準(zhǔn)的代碼
如何獲取編輯的內(nèi)容呢?這個(gè)問(wèn)題很簡(jiǎn)單,只要獲取iframe頁(yè)面body中的innerHTML就可以了:
var content = iframe.contentWindow.document.body.innerHTML;
然而,IE下的innerHTML非常不標(biāo)準(zhǔn):標(biāo)簽名是大寫的,屬性沒(méi)有引號(hào)包起來(lái),單標(biāo)簽也沒(méi)有結(jié)束符……即便是Firefox下獲取的代碼,也有少量瑕疵。這個(gè)時(shí)候就要用正則表達(dá)式對(duì)代碼進(jìn)行標(biāo)準(zhǔn)化處理。
總結(jié)
不多說(shuō)了,做一遍HTML編輯器,你就會(huì)知道CKEditor是多么強(qiáng)大。
相關(guān)文章
asp.net 為FCKeditor開(kāi)發(fā)代碼高亮插件實(shí)現(xiàn)代碼
昨天已經(jīng)將BlogEngine的可視化編輯器換成了FCKeditor,作為一個(gè)程序員,在博客中插入代碼是很重要的一塊。網(wǎng)上現(xiàn)有的都是修改FCKeditor的fckeditorcode_gecko.js和fckeditorcode_ie.js以達(dá)到InsertCode的目的。這個(gè)方法非常麻煩,當(dāng)要使用FCKeditor新版本時(shí)都要重新修改這兩個(gè)文件,非常影響我們的效率。2008-08-08CKEDITOR二次開(kāi)發(fā)之插件開(kāi)發(fā)方法
CKEditor固有的一些文件被組織到_source目錄里. 核心的功能,諸如DOM元素操作,事件處理,初始化腳本和一些環(huán)境設(shè)置被包含在_source\core文件夾內(nèi). 而其它的一些功能, 比如格式化,拷貝和粘貼, 圖片和鏈接, 都被實(shí)現(xiàn)為插件形式放在_source\plugins文件夾內(nèi)2017-03-03百度編輯器 如何獲取光標(biāo)位置與不同幀內(nèi)的節(jié)點(diǎn)
當(dāng)我們console.log(domUtils)的時(shí)候,可以在控制臺(tái)中,看見(jiàn)很多domUtils下的方法,這些方法都是用于操作節(jié)點(diǎn)的,findParentByTagName()顧名思義,獲取的是節(jié)點(diǎn),當(dāng)我們的光標(biāo)在編輯器內(nèi)容處,而我們要獲取相應(yīng)內(nèi)容外層節(jié)點(diǎn)的id以及各種屬性,就需要通過(guò)domUtils來(lái)獲得不同幀內(nèi)的節(jié)點(diǎn)2012-07-07