UEditor官網地址 http://fex.baidu.com/ueditor/
最近使用富文本編輯器Braft Editor、wangEditor多少都有一些問題。於是使用了比較老牌的富文本編輯器UEditor。雖然也有一些問題,但是好在踩過坑的人多,一般的問題都可以解決。這裏總結一下。
1. UEditor實現onChange事件。
UEditor自身提供了contentChange事件,但是UEditor的contentChange事件有bug,按住Shift再輸入內容,不會觸發事件,比如很多標點符號或大寫字母的輸入就無法觸發contentChange事件。 selectionChange事件也有同樣的bug。
處理辦法,監聽UEditor初始化後的iframe中的body的input事件,在這個input事件中手動觸發UEditor的contentChange事件。
var body = ueditor.body;
body.addEventListener('input', function() {
ueditor.fireEvent('contentChange');
});
這樣做存在問題: 對於沒有按住Shift的輸入會觸發兩次contentChange事件,自身封裝的React的組件需要有個過濾,避免一些可能的性能問題。
爲什麼不直接使用input事件呢,因爲富文本內容的有些變化並不是通過input事件引起的。比如插入圖片,這些都由UEditor內部自己去觸發contentChange事件。
2.UEditor中實現placeholder
當富文本中沒有內容的時候給絕對定位顯示一個div。
依然用到iframe中的body。給它綁定focus事件和blur事件。
body.addEventListener('focus', () => {
//隱藏
});
body.addEventListener('blur', () => {
//判斷富文本中是否有內容,決定顯示與隱藏placeholder
});
另外要注意如果手動修改了富文本中的值也要去判斷一下placeholder的隱藏與顯示,比如執行了ueditor.setContent。
點擊到placehlder的div上手動觸發body的focus,隱藏placeholder。
3.刪除UEditor有序列表導出li標籤帶的p標籤。
默認從UEditor中導出的有序列表無序列表是這樣的結構:
<ol><li><p></p></li></ol>
導致使用富文本中內容的時候可能會有顯示上的問題。在UEditor源碼找到一個配置參數:
disablePInList: true, //導出有序列表的時候把p標籤去掉
加上之後導出的就是
<ol><li></li></ol>
這樣了。
4.去掉UEditor的自動保存。enableAutoSave:false
UEditor有一個自動保存的功能,默認會把編輯器中的內容保存到localStorage中。這個功能不需要的話配置enableAutoSave:false可以關閉。
但是要注意1.4的版本這樣配置可能沒有用。 需要到github上下載1.5的版本自己grunt編譯一下使用。
5.百度UEditor編輯器關閉抓取遠程圖片功能 catchRemoteImageEnable: false
測試發現上傳圖片之後再執行一些粘貼操作的時候,原來上傳的圖片全部變成了loading狀態,不能正常顯示。這是因爲對於不同域的圖片,ueditor會嘗試重新上傳到本域,就會出現這樣的情況。
6.輸出過濾。
在圖片上傳中用戶執行提交操作,這個時候取到的富文本內容會包含一個<img class="loadingclass">
這樣的loading圖。 這顯然是不合理的。
處理辦法是在contentChange的時候往組件上層傳遞onChange(value)的時候對value進行過濾。
比如使用jq過濾。注意要儘量減少過濾操作。在組件中緩存過濾前的值,如果值沒變,就不去執行過濾,不往上觸發onChange事件。
var html = ueditor.getContent();
var filterdHtml =
$(`<div>${html}</div>`)
.find('.loadingclass')
.remove()
.end()
.prop('innerHTML') || '';
該功能可通過修改上傳圖片的插件實現,見第8條。
7.UEditor前後端解耦。
UEditor有部分配置會在後端,比如圖片上傳的部分配置,UEditor會調接口去請求。 這不符合我們的項目情況:一來服務端不一定方便給你返回這個配置也沒有比要,二來用UEditor中的方法來加載這個配置文件還很容易遇到跨域的問題。
修改源碼:
1.將原來服務端返回過來的配置放到 ueditor.config.js中。 比如圖片上傳的配置。
2.修改源碼ueditor.all.js中loadServerConfig方法。 註釋掉setTimeout方法中try …catch請求服務端內容相關的內容,需要以下兩句以保持編輯器的其他邏輯正常。
me.fireEvent(‘serverConfigLoaded’);
me._serverConfigLoaded = true;
8.UEditor使用自定義接口圖片上傳。
一般公司都有固定的中臺上傳接口和返回格式,跟ueditor的不一樣。所以用ueditor上傳有2個方案。一個是新寫一個上傳組件顯示在工具欄,二個是修改自帶的上傳組件simpleupload。這裏採用第二種,修改插件。
這個插件使用了iframe來上傳,實際應用中也會出現跨域的問題。所以我們修改它的上傳方法。拿到file後 根據配置文件的的格式和內容來判斷文件是否符合要求,然後使用
var xhr = new XMLHttpRequest();
var fd = new FormData();
來上傳並執行回調。
上傳成功或失敗需要設置 input.value="" 避免再次上傳同一個文件時點擊按鈕無反應。
輸出過濾:getContent的時候過濾掉上傳中和上傳失敗的圖片,在該插件的outputRule中添加 loadingclass的過濾。
if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) {
n.parentNode.removeChild(n);
}
9.UEditor自定義事件的應用。使用antd的message組件給Ueditor報錯。
在ueditor.all.js中,上傳失敗的時候,觸發一個自定義事件:me.fireEvent(‘antdError’, ‘上傳失敗’);
然後在封裝的react組件中監聽antdError事件就可以了。