摘要:前言本文將介紹筆者在的項目中使用百度的富文本編輯器的過程。以百度官網(wǎng)的為例,控制臺輸入為該編輯器注冊點擊事件,當(dāng)點擊加粗按鈕時,控制臺輸出為了避免點擊工具條時觸發(fā)事件,筆者將自定義的事件全部注釋了。
前言
本文將介紹筆者在React的項目中使用百度的富文本編輯器Ueditor的過程。注意本文不提供一條龍式的使用方法,只是將使用過程中的一些實現(xiàn)思路進行總結(jié),供以參考。react項目中導(dǎo)入ueditor,會存在各種不正交的問題,需要注意。
引入首先在ueditor官網(wǎng)下載最新安裝包,然后在項目入口的html中導(dǎo)入(導(dǎo)入方式不一,可以采用import的方式,需要自行度娘。但是無論哪種引入方式,只要想自定義功能,不正交問題就難以避免QAQ)。不管三七二十一先跑起來再說。。
ueditor demo ······
在React項目中使用ueditor要注意
導(dǎo)入的路徑,筆者使用的是項目經(jīng)webpack打包之后的相對路徑。
導(dǎo)入順序,配置文件要先于源碼。
筆者這種引入方式存在緩存問題,所以修改ueditor.all.js后需要及時清理緩存,測試新的代碼。
封裝/** * 封裝UEditor */ import React from "react"; import "./index.less"; class UEditor extends React.Component { constructor(props) { super(props); this.editor = {}; this.id = ""; } ······ componentDidMount() { let UE = window.UE; let id = this.id; if (id) { try { /* 加載之前先執(zhí)行刪除操作,否則如果存在頁面切換, 再切回帶編輯器頁面重新加載時不刷新無法渲染出編輯器 */ UE.delEditor(id); } catch (e) {} let ueditor = UE.getEditor(id, { toolbars: [ ["bold", "italic", "underline", "kityformula", "diyimg"] ], initialContent: "", autoHeightEnabled: false, autoFloatEnabled: false, elementPathEnabled: false, wordCount: false, enableAutoSave: false, initialFrameWidth: this.props.width, initialFrameHeight: this.props.height }); } } render() { this.id = this.props.id; return ; } } export default UEditor;
筆者在項目中使用了加粗,斜體,下劃線,插入圖片,公式等功能,想要自定義配置均可參照ueditor.config.js修改。具體的將一一介紹,最后實現(xiàn)效果如下:
問題總結(jié): 1. 禁止自動增高,改用滾動條autoHeightEnabled: false initialFrameWidth:this.props.width initialFrameHeight:this.props.height
autoHeightEnabled可以阻止自動增高,然后再自定義容器寬度和高度。
2. 自定義全局樣式,如容器的padding,p標簽的line-height等解決方法:ueditor.all.js的第6800多行的render方法,在其中可以自定義全局樣式。
3. 導(dǎo)航條切換后,無法再次渲染解決方法:在每次ueditor實例化之前,先刪除對應(yīng)的id
UE.delEditor(id);
原因分析:
從實例化和卸載實例的源碼來看:
getEditor:
UE.getEditor = function (id, opt) { var editor = instances[id]; if (!editor) { editor = instances[id] = new UE.ui.Editor(opt); editor.render(id);//渲染編輯器 } return editor; };
delEditor:
UE.delEditor = function (id) { var editor; if (editor = instances[id]) { editor.key && editor.destroy(); delete instances[id] } };
UE在全局管理了一個實例池,每次實例化都會根據(jù)id檢索,然后生成實例。從getEditor的源碼中可以看出,ueditor的一個實例在第一次初始化時存在一個editor.render(),這是將此id的實例渲染到對應(yīng)的id容器上。然而,當(dāng)用戶tab切換編輯器再切回來時,此時由于該實例已在實例池中存在,于是直接執(zhí)行return editor,所以少了editor.render()這一步,于是不能重新渲染。所以,在Ueditor組件每次實例化之前,先進行delEditor卸載。這里需要注意,從delEditor中可以看出ueditor卸載實例時調(diào)用了實例的destroy方法。從destroy的注釋來看:銷毀編輯器實例,使用textarea代替 ,這解釋了為什么在切換編輯器或者卸載編輯器時,會出現(xiàn)編輯器變?yōu)閠extarea的情況,如圖所示:
4. 模擬placeholder實現(xiàn)預(yù)置文案解決方法:在UE的實例中自定義方法,實現(xiàn)填充文字模擬placeholder的效果,代碼如下:
//模擬placeholder和控制toolbar顯示隱藏 UE.Editor.prototype.initDiy = function (placeholder) { var _editor = this; //獲取焦點 _editor.addListener("focus", function () { UE.isEditored = true; var Text = `${placeholder}
` var localHtml = _editor.getContent(); if (localHtml === Text) { _editor.setContent("");//點擊時清空 _editor.focus(true); } //使得其他工具條display置為none var list = document.querySelectorAll(".edui-editor-toolbarbox"); list.forEach((ele) => { ele.style.display = "none"; }); var toolbar = findKey(_editor.key); toolbar.style.display = "block"; }); // 插入圖片時存在問題 // _editor.addListener("blur", function () { // var localHtml = _editor.getContent(); // if (localHtml === "") { // _editor.setContent(`${placeholder}
`); // } // // window.activeEditor = _editor.key; // }); _editor.ready(function () { // _editor.fireEvent("blur"); _editor.setContent(`${placeholder}
`);//填充預(yù)置文案 }); } //尋找工具條 function findKey(key) { let ele = document.querySelector(`#${key}`); let toolbar = ele.querySelector(".edui-editor-toolbarbox"); return toolbar; }
原來,筆者實現(xiàn)的效果是點擊時清空,失焦時還原。但是,在做自定義工具條時產(chǎn)生了bug(在5中我會細說),因此我采用了另一種方案:初始時設(shè)置預(yù)設(shè)文案,當(dāng)用戶聚焦時清空預(yù)設(shè),用戶失焦后不再恢復(fù)該預(yù)設(shè)文案。也就是將blur事件注釋了。。。
5. 工具條顯示在編輯器頭部,顯示為懸浮效果,默認隱藏,聚焦時出現(xiàn)實現(xiàn)思路:將themes/default/css/ueditor.css中加入:
.edui-default .edui-editor-toolbarbox { position: absolute; ······ top: -36px; }
首先實現(xiàn)頭部偏移,然后通過控制toolbar對應(yīng)dom元素的display來隱藏工具條。實現(xiàn)效果如下:
下面解釋一下為什么編輯器失焦的時候不恢復(fù)預(yù)置文案:
從4中的代碼可以看出,我們是通過觸發(fā)focus和blur事件分別清空和填充編輯器的內(nèi)容。但是當(dāng)我們點擊工具條時,編輯器就會觸發(fā)blur事件!!于是就會出現(xiàn)各種bug。以百度官網(wǎng)的ueditor為例,控制臺輸入:
為該編輯器注冊點擊事件,當(dāng)點擊加粗按鈕時,控制臺輸出:
為了避免點擊工具條時觸發(fā)blur事件,筆者將自定義的blur事件全部注釋了。
6. 自定義按鈕和七牛云圖片上傳首先,在ueditor.config.js中找到toolbars數(shù)組,增加一個diyimg字符串,然后在zh-cn.js找到labelMap數(shù)組,在末尾加上"diyimg": "插入圖片" 。最后,在ueditor.all.js中找到btnCmds數(shù)組,加入diyimg字符串。初始化時使用這個字符串,工具條上就會顯示一個按鈕,但是我們發(fā)現(xiàn)他顯示的是這樣的:
這是因為ueditor默認使用加粗的icon作為自定義按鈕的默認icon,所以為了使用默認的插入圖片的圖標,我們需要到themes/default/css/ueditor.css中,在最后一行加入:
/*自定義圖片上傳按鈕 */ .edui-default .edui-toolbar .edui-for-diyimg .edui-icon { background-position: -380px 0px;//這個位置是“插入圖片”的icon,其他圖標可自行調(diào)整 }
添加后,顯示效果如下:
圖標正常顯示后,需要為該圖標添加相應(yīng)的點擊事件,在ueditor.all.js中加入:
//圖片上傳 UE.commands["diyimg"] = { execCommand : function(){ const upload = async(e) => { ······//完成圖片上傳的代碼 } const fileInput = document.getElementById("diyimg");//獲取dom上隱藏的一個input標簽 fileInput.onchange = upload; fileInput.click();//觸發(fā)input標簽實現(xiàn)文件上傳 return true; }, queryCommandState:function(){ } };
筆者這里不贅述圖片上傳的代碼,度娘上很多,我簡單說說實現(xiàn)的思路:
先實現(xiàn)一個插入圖片的按鈕,然后為該按鈕注冊相應(yīng)的事件diyimg,然后在頁面中添加一個input file標簽并隱藏,diyimg事件會觸發(fā)該標簽的點擊事件,彈出文件上傳彈窗,此時選擇文件點擊后會觸發(fā)onchange事件,執(zhí)行相應(yīng)的圖片上傳代碼。上傳成功到服務(wù)器后,服務(wù)器會返回圖片對應(yīng)的url,此時拿到該url填入對應(yīng)編輯器實例,執(zhí)行編輯器的插入圖片的代碼:
this.execCommand("insertimage", { src: res.data.downloadUrl,//回調(diào)傳來的url width:"60" // height:"45" });7. 給在編輯器內(nèi)部的img等標簽添加內(nèi)聯(lián)樣式
ueditor默認存在xss過濾!!!這里以給img標簽添加style=“vertical-top”為例。
首先要找到ueditor.config.js,在其中搜索xss,在第403行左右有代碼:
img: [src", "alt", "title", "width", "height", "id", "_src", "loadingclass", "class", "data-latex"],
往數(shù)組里加入style字符串,然后在ueditor.all.js中搜索UE.commands["insertimage"] ,在第約11172行找到str,往里面加入內(nèi)聯(lián)樣式即可。
一些吐槽: 1. 在react項目里使用script形式引入,感覺格格不入 2. 為了實現(xiàn)placeholder,各個事件之間存在不正交的現(xiàn)象。諸如點擊按鈕,卻觸發(fā)了編輯器的失焦事件 3. 在使用自定義的字數(shù)限制功能時,筆者使用ueditor的contentChange去檢測內(nèi)容字數(shù),但是contentChange事件是定時的,所以計算字數(shù)會有問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/52900.html
摘要:前言本文將介紹筆者在的項目中使用百度的富文本編輯器的過程。以百度官網(wǎng)的為例,控制臺輸入為該編輯器注冊點擊事件,當(dāng)點擊加粗按鈕時,控制臺輸出為了避免點擊工具條時觸發(fā)事件,筆者將自定義的事件全部注釋了。 前言 本文將介紹筆者在React的項目中使用百度的富文本編輯器Ueditor的過程。注意本文不提供一條龍式的使用方法,只是將使用過程中的一些實現(xiàn)思路進行總結(jié),供以參考。react項目中導(dǎo)入...
VSCode使ReactVue代碼調(diào)試變得更爽 在前段開發(fā)中,大家會遇見調(diào)試 Vue/React 代碼,現(xiàn)在就給大家總結(jié)都有哪幾種: 先找代碼問題,在console.log 打印日志,用 Chrome Devtools 的 debugger 來調(diào)試,用 VSCode 的 debugger 來調(diào)試。 看到是不是不同,不僅效率大大提升就連體驗也是超級幫的,這種體驗讓人超級爽到爆炸。 很多...
這是講 ahooks 源碼的第一篇文章,簡要就是以下幾點: 加深對 React hooks 的理解。 學(xué)習(xí)如何抽象自定義 hooks。構(gòu)建屬于自己的 React hooks 工具庫。 培養(yǎng)閱讀學(xué)習(xí)源碼的習(xí)慣,工具庫是一個對源碼閱讀不錯的選擇。 注:本系列對 ahooks 的源碼解析是基于v3.3.13。自己 folk 了一份源碼,主要是對源碼做了一些解讀,可見詳情。 第一篇主要介紹 a...
在這里為大家介紹,實現(xiàn)多張圖自動輪播可以用react-slick插件,下面一起看看: 一、進入官網(wǎng)查看文檔(Docs) react-slick官網(wǎng) 二、安裝插件(Quick Start) //npm安裝 npminstallreact-slick--save //yarn安裝 yarnaddreact-slick 三、范例使用(Examples) 在examples在擴...
用vite作為項目打包工具,這是為什么?其中最主要的原因是 ——vite在開發(fā)環(huán)境基于ESM規(guī)范實現(xiàn)的Nobundle模式,節(jié)省了代碼打包的時間。 當(dāng)前打包的需求任然有,且ESM規(guī)范兼容性越來越好,進入生產(chǎn)環(huán)境大面積可用的狀態(tài)也不是不可能。 當(dāng)生產(chǎn)環(huán)境打包將不再是剛需時。 另一方面,從HTTP協(xié)議的角度看,在HTTP/1.1時代,多個模塊被打包成一個文件能減少瀏覽器并發(fā)請求數(shù),達到優(yōu)化目...
閱讀 2420·2021-11-18 10:02
閱讀 687·2021-10-08 10:04
閱讀 2250·2021-09-03 10:51
閱讀 3540·2019-08-30 15:44
閱讀 2799·2019-08-29 14:09
閱讀 2464·2019-08-29 12:21
閱讀 2064·2019-08-26 13:45
閱讀 1800·2019-08-26 13:25