UEditor如何進行二次開發

如何進行二次開發

背景

UEditor 雖然功能衆多,但對於廣大開發者來說,還是有很多定製化的功能需求,如果都靠UEditor團隊自己開發那是不現實的,這時就需要廣大開發者在UEditor的基礎上自己開發定製功能。但在之前的版本中,UEditor對於二次開發的支持不夠優化,經常需要開發者不僅要開發相應的功能,例如command命令,plugin插件等,還要在UEditor上修改多處文件,例如,添加按鈕,添加樣式等等,才能將功能添加到UEditor中。這樣的方式對於以後的升級和後續定製功能的維護,都會造成維護困難的問題。介於次,UEditor從1.4.1開始,添加對於二次開發的擴展支持。

二次開發方式

無需對 UEditor 代碼做任何修改,只需在UEditor之外通過UEditor提供的二次開發接口開發定製功能.這種開發方式不僅避免了修改UEditor源碼,方便日後UEditor的升級,而且通過接口,可以將開發的定製功能維護到一個文件中或者一個目錄中,方便日後對其維護。

部署定製功能

對於 UEditor 的二次開發,一般多爲添加按鈕,下拉筐或者是添加一個dialog。基於這幾種常規的方式,我在_examples目錄下分別書寫了3個類型的定製demo。

  1. addCustomizeButton.js 添加一個按鈕
  2. addCustomizeCombox.js 添加一個下拉框
  3. addCustomizeDialog.js 添加一個彈出層

除了添加彈出層需要一個而外的html頁面外,對於需要添加和修改的功能代碼全部都維護到一個js文件中了。

使用文件的方式:

<script type="text/javascript" charset="utf-8" src="../ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="editor_api.js">
</script>
<script type="text/javascript" charset="utf-8" src="../lang/zh-cn/zh-cn.js"></script>
<!--添加按鈕-->
<script type="text/javascript" charset="utf-8" src="addCustomizeButton.js"></script>

新添加的按鈕就完成了。實例化編輯器時,無需再而外添加任何代碼。

開發細節

前面講了如何部署你的功能,這個小節來和大家講一下,UEditor提供那些接口,讓大家可以在編輯器之外擴展你的功能。

UE.registerUI('uiname', function(editor, uiname) {
    //do something
}, [index, [editorId]]);

考慮到大家的功能基本上都會擴展一個UI和這個UI做的事情,所以UEditor提供了registerUI這個接口,可以讓開發者動態的注入擴展的內容。

  1. uiname,是你爲新添加的UI起的名字,這裏可以是1個或者多個,“uiname”後者是“uiname1 uiname2 uiname3”
  2. function,是實際你要做的事情,這裏提供兩個參數,editor是編輯器實例,如果你有多個編輯器實例,那每個編輯器實例化後,都會調用這個function,並且把editor傳進來,uiname,你爲ui起的名字,如果前邊你添加的是多個的化,這裏function會被調用多次,並且將每一個ui名字傳遞進來.如果函數返回了一個UI 實例,那這個UI實例就會被默認加到工具欄上。當然也可以不返回任何UI。比如希望監控selectionchange事件,在某些場景下彈出浮層,這時就不需要返回任何UI.
  3. index,是你想放到toolbar的那個位置,默認是放到最後
  4. editorId,當你的頁面上有多個編輯器實例時,你想將這個ui擴展到那個編輯器實例上,這裏的editorId是給你編輯器初始化時,傳入的id,默認是每個實例都會加入你的擴展

添加按鈕

添加一個按鈕

UE.registerUI('button', function(editor, uiName) {
    //註冊按鈕執行時的command命令,使用命令默認就會帶有回退操作
    editor.registerCommand(uiName, {
        execCommand: function() {
            alert('execCommand:' + uiName)
        }
    });
    //創建一個button
    var btn = new UE.ui.Button({
        //按鈕的名字
        name: uiName,
        //提示
        title: uiName,
        //添加額外樣式,指定icon圖標,這裏默認使用一個重複的icon
        cssRules: 'background-position: -500px 0;',
        //點擊時執行的命令
        onclick: function() {
            //這裏可以不用執行命令,做你自己的操作也可
            editor.execCommand(uiName);
        }
    });
    //當點到編輯內容上時,按鈕要做的狀態反射
    editor.addListener('selectionchange', function() {
        var state = editor.queryCommandState(uiName);
        if (state == -1) {
            btn.setDisabled(true);
            btn.setChecked(false);
        } else {
            btn.setDisabled(false);
            btn.setChecked(state);
        }
    });
    //因爲你是添加button,所以需要返回這個button
    return btn;
});

添加多個

UE.registerUI('bold italic redo undo underline strikethrough', function(editor, uiName) {
    //註冊按鈕執行時的command命令,使用命令默認就會帶有回退操作
    editor.registerCommand(uiName, {
        execCommand: function() {
            alert('execCommand:' + uiName)
        }
    });
    //創建一個button
    var btn = new UE.ui.Button({
        //按鈕的名字
        name: uiName,
        //提示
        title: uiName,
        //添加額外樣式,指定icon圖標,這裏默認使用一個重複的icon
        cssRules: 'background-position: -500px 0;',
        //點擊時執行的命令
        onclick: function() {
            //這裏可以不用執行命令,做你自己的操作也可
            editor.execCommand(uiName);
        }
    });
    //當點到編輯內容上時,按鈕要做的狀態反射
    editor.addListener('selectionchange', function() {
        var state = editor.queryCommandState(uiName);
        if (state == -1) {
            btn.setDisabled(true);
            btn.setChecked(false);
        } else {
            btn.setDisabled(false);
            btn.setChecked(state);
        }
    });
    //因爲你是添加button,所以需要返回這個button
    return btn;
});

在完整版本的下載包裏,我寫了3個例子,添加一個按鈕,下拉筐,彈出一個浮層,大家可以參考

總結

之前UEditor對於第三方的開發確實支持的不夠靈活,導致爲了開發還要污染UEditor本身,這爲後學升級添加了麻煩。當然現在這個設計可能還有考慮不到的地方,大家可以直接發issue給我們,我們會進行及時的補丁,並在後續的版本中更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章