提到富文本,可能大家都用到過百度的ueditor,作為一個重量級的插件,總結起來一句話,功能很強大,使用很費心。不知道是不是太久沒有維護了,ueditor的文檔可讀性還真是差也可能是悟性不夠吧。本文也不是使用教程,只是簡單總結一下如何更改字體設置為rem。
一、問題
因為ueditor是pc端的富文本,所以一切字體大小都是以px為單位,但是我們項目需要在移動端來顯示,並且移動端的項目都類似淘寶flexible那樣做了高清屏幕的適配,這樣原原本本的pc上的發布的內容在app上可能就張下面這個樣子了:
因為高清屏下面,進行了viewport的縮放,所以固定的px就不適用了。
二、解決思路
解決方法有兩個:
1、移動端直接放棄適配方案,不過這樣還是要對圖片進行一下處理,設置個width:100%否則屏幕就被撐開了。
2、在ueditor編輯的時候,根據與app相同的策略來使用rem來代替其固有的px,同時頁面根元素設置與app使用的font-size
對比而言,肯定第一種比較快,但還是繞過去了問題,第二個就要閱讀源碼了,還是讓我們一起來看一下如何進行第二種方案。
詳細來說,第二種方案要求有下面這么兩個:
1、pc上html設置font-size與app保持一致(我們以50px為例),確保dpr為1情況下相同元素在pc和app兩端是相同的的。例如14px,在app屏幕dpr為1(即非高清屏)的情況下為0.28rem,同樣在pc上也應該為0.28rem。也就是將ueditor中的字體選項10-28px的選項對應*0.02。
2、考慮我們的用戶並不知道rem,所以展示還是要是14px這樣的形式
三、實現
根據上面的要求,要想修改ueditor的源碼,首先得捋一下相關代碼具體在哪,對於ueditor.all.js那幾千行的代碼來說,如果一點點看下去,顯然有點不可取。我們應該搜索關鍵字。我們先看一下ueditor字號相關的部分長什么樣子:
可以看到這部分的特殊的class是edui-for-fontsize,只有一個,代碼如下
到這里大家應該就可以看出來設置字體和顯示的地方了,具體看代碼
1 // @todo 修改為rem 2 // var size = list[i] + 'px'; 3 var size = (list[i]*2/100 )+ 'rem'; 4 items.push({ 5 // 字體欄顯示的大小選項,這里還是顯示px 6 label:list[i]+'px', 7 // 真正的值 8 value:size, 9 theme:editor.options.theme, 10 // 可以從這里看出來,this.label顯示 font-size就是字體大小了 11 renderLabelHtml:function () { 12 return '<div class="edui-label %%-label" style="line-height:1;font-size:' + 13 this.value + '">' + (this.label || '') + '</div>'; 14 } 15 });
到這里起碼看起來像那么回事了,展示的是px其實是rem。但是還有一個問題,每次切換字體大小之后都會變為0rem。
這個就太神奇了,明明沒有零的存在呀。肯定是ueditor做了計算然后得出的。下面就是打斷點尋找了。這個過程就不贅述了。發現了下面這段代碼:
// 當修改字體的時候回去進行計算,因為px肯定是整數,所以會進行下面的做法 // 但是我們轉成rem之后就是0.n,這樣就有問題了 var styleVal = domUtils.getComputedStyle(startNode, style), tmp = /^([\d\.]+)(\w+)$/.exec( styleVal ); if( tmp ) { // @todo 修復計算問題,如果rem結尾說明是自身修改,改變計算方法 if(tmp[2] == 'rem'){ return parseInt(tmp[1] * 50) + 'px' } // 計算出來之后,0.nrem得到的只是orem return Math.floor( tmp[1] ) + tmp[2]; } return styleVal; }
改完之后可以查看下顯示,正常了。但是好像設置了之后字體並沒有真正的那么大。這又是為什么呢?
老辦法,直接打開控制台查看吧,看這段p到底是什么樣式。
可以看出來這里確實是對應的0.72rem了,html是50px的基礎size的話,為什么不生效呢。且慢,我們看一下輸入框里的內容都是嵌在iframe里的,這下就明白了,我們給iframe設置個font-size就好了。在ueditor->theme->iframe.css下面我們可以進行設置
到這里我們的改造就基本完成了。
四、總結
前面提到了,本文不是ueditor的教程,可能大神會有更簡潔的方式。看起來也就這么點代碼量,涉及的東西也不多,但當時確實花了我不少的時間。對我而言可能更多的收獲還是解決和定位問題的能力的鍛煉。其實對於我們程序員來說修bug的能力是相當重要的,不僅僅是自己寫出來的,也許是第三方插件的,也許正常情況下不是問題,但是用到我們具體的場景下某些條件就成了限制。最難修的永遠是別人的bug,遇到這種情況,最重要的不盲目和自信,繞過去的問題永遠是你的問題,敢於去迎接挑戰才能提升自己。