1. 程式人生 > >解決UEditor樣式被過濾問題實戰

解決UEditor樣式被過濾問題實戰

上週開發中有用到開源的富文字編輯器UEditor,在使用的過程中遇到了樣式被過濾無法顯示問題,經過一番折騰終解決,此外,還有一些關於獲取前臺介面元素的一些總結。

1. UEditor樣式被過濾無法顯示問題
         上週有用到百度開源的富文字編輯器----UEditor.不得不說這個富文字編輯器做的真的很贊,個人覺得比CKeditor要好用很多,效果也很不錯。
但是在使用的過程中,有遇到在向文字編輯器插入HTML文字時,新增的樣式老是被過濾掉,找了很多的資料,並結合最新的版本,整理了下如何解決樣式過濾的方法。
我們在富文字編輯頁點選HTML小圖示,切換到HTML模式,然後在該模式下加入如下HTML:

123456<style type="text/css">.bg{ background:lightbule;}</style><divclass="bg">Hello EveryBody Welcome To UEditor World!</div>

以上的html意思很簡單,就是為div加了一個名為bg 的樣式,
然後我們再點選HTML圖示,轉換到預覽頁,可以看到我們的div的背景色並沒有任何的變化,而且我們在div之前寫的樣式,也沒有被渲染,
反而是以文字的形式顯示了出來。
F12檢視整個頁面,發現我們之前寫的樣式和標籤都被渲染成如下的html:

1234<div style="display: none;"cdata_tag="style"type="text/css"><p>Hello EveryBody Welcome To UEditor World!</p>

由以上程式碼可以看出,我們的style標籤被轉換成了div,並且設定樣式為不可見,我們的div標籤被轉換成了p標籤。
這說明編輯器本身自己做了一個轉換,類似於一個過濾吧,可能是為了出於安全性考慮,防止使用者在前段輸入非法的程式碼、指令碼等,事實上我覺得這有點多此一舉,
既然都讓富文字編輯了,不能寫html指令碼,還叫什麼富文字。
然後我們再點選HTML圖示,看看HTML試圖,內容如下:

1234<style type="text/css">.bg{ background:lightbule;}</style><p>Hello EveryBody Welcome To UEditor World!</p>

結合以上分析得出,該編輯器內部過濾機制是將style標記轉換為div,而將div等標籤以p替代。如何解決呢?
之前有在網上查過相關的資料,都說是在配置檔案裡有一個黑白名單,然後就在配置檔案裡找了下,在最新版本的指令碼檔案裡怎麼找也沒找到那個所謂的黑白名單,
當然了,沒有黑白名單也照樣可以解決問題的。
首先在ueditor.all.js檔案內搜尋allowDivTransToP,找到如下的程式碼,將true設定為false
me.setOpt('allowDivTransToP',false);
//預設的過濾處理
//進入編輯器的內容處理
然後再接著下邊的addInputRule方法中將switch程式碼段中的case style,script都給註釋或者刪掉。
me.addInputRule(function (root) {
var allowDivTransToP = this.options.allowDivTransToP;
var val;
//進行預設的處理
root.traversal(function (node) {
if (node.type == 'element') {
if (!dtd.$cdata[node.tagName] && me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) {
if (!node.firstChild()) node.parentNode.removeChild(node);
else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) {
node.parentNode.removeChild(node, true)
}
return;
}

//刪除switch下的case style 和script
switch (node.tagName) {
case 'a':
if (val = node.getAttr('href')) {
node.setAttr('_href', val)
}
break;
完成以上操作之後,儲存即可。再次插入html時,樣式就可以顯示了。
解釋一下以上操作的意義。
第一步將allowDivTransToP設定為false是因為預設的設定是將div自動轉換為p,這樣寫好的樣式就找不到相應的div
了,所以才渲染不上的。
第二步將addInputRule函式中的switch 程式碼段中的case style ,script選擇給刪除或者註釋,是為了避免出現編輯器將style或script自動的轉換成別的標籤。
好了,大家可以試一試,看看效果。