天天看點

線上編輯器的基本實作原理

      如今網站開發越來越提倡使用者體驗,為使用者提供便利的工具也越來越多,而線上的HTML内容編輯器應該算是其中比較“古老”的一個了。功能簡單的可以為使用者提供文本的樣式控制,例如文字的顔色、字型大小等;而功能複雜的甚至可以提供類似Word一樣的強大功能。雖然現在各種開源的編輯器非常多,但是真正好用的并不多,是以它們改進工作也一直在進行中。

       如今網上多數的編輯器都有很強大的功能,相對而言,在使用中也需要很多的配置,當然代碼也自然會比較“臃腫”。如果我們并不需要功能那麼強大的編輯器,那麼可以自己實作一個,因為代碼并不複雜。下面是一點個人的經驗,僅供參考(以ExtJS的HTMLEditor為例)。

      1、初始化。當頁面加載完畢後,向頁面添加一個IFrame(可選)。這裡要注意的是,要判斷頁面的狀态,要等頁面完全加載完畢後再進行操作,防止出現找不到某些元素的錯誤。

      2、打開編輯功能。将IFrame設為可以編輯(下面代碼來自ExtJS的HTMLEditor):

      // 擷取iframe的window對象

getWin : function(){

return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];

},

//擷取iframe的document對象

getDoc : function(){

return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);

//打開document對象,向其寫入初始化内容,以相容FireFox

doc = this.getDoc();

doc.open();

doc.write('<html><head><mce:style type="text/css"><!--

body{border:0;margin:0;padding:3px;height:98%;cursor:text;}

--></mce:style><style type="text/css" mce_bogus="1">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>');

//打開document對象編輯模式

doc.designMode = "on";

doc.close();

      這樣就可以向這個簡單那的編輯器中寫入内容了。

      3、擷取編輯器的内容,代碼如下:

      //擷取編輯器的body對象

var body = doc.body || doc.documentElement;

//擷取編輯器的内容

var content = body.innerHTML;

//對内容進行處理,例如替換其中的某些特殊字元等等

//Some code

//傳回内容

return content;

      4、增加樣式設定。上面的編輯器雖然實作了基本功能,但是實在是有些太簡單了,應該增加些簡單的樣式實作。document的execCommand方法使這種想法成為可能。

     //統一的執行指令方法

function execCmd(cmd, value){

//doc對象的擷取參照上面的代碼

//調用execCommand方法執行指令

doc.execCommand(cmd, false, value === undefined ? null : value);

};

//将選中字型變為黑體,Ctrl-B

execCmd('bold');

//加下劃線,Ctrl-U

execCmd('underline');

//變為斜體,Ctrl-I

execCmd('italic');

//設定文字的顔色

execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);

//在光标處插入一段内容

function insertAtCursor(text){

//win對象的擷取參考上面的代碼

if(Ext.isIE){

win.focus();

var r = doc.selection.createRange();

if(r){

r.collapse(true);

r.pasteHTML(text); }

}else if(Ext.isGecko || Ext.isOpera){

execCmd('InsertHTML', text);

}else if(Ext.isSafari){

execCmd('InsertText', text);

}

     5、再進一步。如今可以改變樣式了,如果編輯器有工具欄(這應該是必然的),那麼我們還想工具欄上的按鈕根據光标所處位置的樣式,自動處于突出或正常顯示。document的queryCommandState()方法又讓這種想法得以實作。

     //doc對象的擷取參考上面的對面

//光标處是否是粗體

var isBold = doc.queryCommandState('bold');

if(isBold){

//改變Bold按鈕的樣式

//當然上面的代碼是可以合并的,這裡隻不過是一個示意

//下劃線

doc.queryCommandState('underline');

//斜體

doc.queryCommandState('italic');

     本文隻是為實作編輯器提供了簡單的思路,其中的一些代碼是可以直接使用的。建議,想自己實作編輯器的朋友可以參考下ExtJS中的HTMLEditor代碼,既簡單又比較清晰,可以在其上進行擴充。

     最後提醒一點:一定要注意浏覽器的相容性問題,并且不要等接近尾聲了再去測試相容性,對于這麼大量的JavaScript代碼,調整是比較痛苦的事情。

繼續閱讀