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)題
用戶(hù)不可能總是在編輯器中輸入,比如加粗、插入圖片等功能是通過(guò)按鈕操作的。假設(shè)用戶(hù)要加粗一段選中的文字,當(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)了。
回車(chē)問(wèn)題
在IE下,按回車(chē)是換段落,生成p>,但在Firefox下是換行,生成的是br>。要解決這個(gè)問(wèn)題,就要監(jiān)聽(tīng)keydown事件,如果檢測(cè)到按鍵是回車(chē),就插入“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)簽名是大寫(xiě)的,屬性沒(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)大。