記錄一下最近使用Ueditor富文本編輯器時遇到的問題javascript
用戶在編輯富文本內容時,好比上傳了10張圖片保存,下一次編輯時去掉了其中3張圖片,那麼數據庫中當前文檔與文檔上傳的文件的對應關係應該如何更新呢?html
我採用的作法是,每次從新獲取富文本中的文件,而後清除文檔與文件的關係後,按當前文檔中獲取來的文件列表從新添加關係java
不採用正則表達式這種效率低的方式node
在上傳文件時將文件內容作md5運算生成惟一key,而後將須要記錄的文件內容都存儲到數據庫中的表中正則表達式
我採用md5運算方法邏輯是,若是文件大於2MB就取文件頭1MB和後1MB,作md5運算生成文件惟一標識,小於2MB就直接md5數據庫
不要問我爲何用頭1MB和後1MB運算生成的MD5值做作惟一標識,用就完了json
UEditor 工具欄配置 app
var ueToolbars = [ [ 'undo', //撤銷 'redo', //重作 'bold', //加粗 'indent', //首行縮進 'italic', //斜體 'fontsize', //字號 'simpleupload', //單圖上傳 'insertvideo', //視頻 'justifyleft', //居左對齊 'justifyright', //居右對齊 'justifycenter', //居中對齊 'justifyjustify', //兩端對齊 'attachment', //附件 ] ]
須要修改ueditor.all.js源碼,在回顯與保存文檔時給相應標籤增長兩個屬性dom
一、t_crc="7d90bcfc87c1e8a918b38f35a6186f53",文件惟一標識ID,文件內容MD5值編輯器
二、t_tag="cxUeditorUploadFile",在標籤中打入標記,以後保存時使用原生js方式獲取帶有標記的全部標籤,這樣就獲取到了文件惟一標識crc字段
如上傳的圖最終保存爲 :
<!-- 圖片 --> <img src="/preview/20190429/20190429182137525982_98488150.jpg" title="191322z2g2mmnoloqzcqnq.jpg" _src="/preview/20190429/20190429182137525982_98488150.jpg" alt="191322z2g2mmnoloqzcqnq.jpg" t_crc="7d90bcfc87c1e8a918b38f35a6186f53" t_tag="cxUeditorUploadImage">
須要注意的是,UEditor中的標籤屬性有名單驗證,須要修改ueditor.config.js中的白名單whitList,增長t_crc,t_tag,不然UEditor會過濾掉咱們自定義的屬性
由於不清楚如何自定義controller的返回字段,看了官網也沒找到如何能自定義返回字段,沒有辦法只能將其中一個字段改成json字符串,然修改ueditor源碼解析改字符串,是否是很low,我也不想這樣寫實在是沒辦法
{ "original": "xy.png", "state": "SUCCESS", "title": "xy.png", "url": "{\"crc\":\"fe760006af17c5bfe2d68ad17f5fe8f6\",\"url\":\"/preview/20190430/20190430105610120347_98488150.png\"}" }
注意源碼中的ueditor.all.js源碼中7966行的filterInputRule方法,執行editor.setContent方法和執行'inserthtml'命令後,會運行該過濾函數,咱們直接加入return;不然咱們本身加的標籤他會過濾掉
/** * 執行註冊的過濾規則 * @method filterInputRule * @param { UE.uNode } root 要過濾的uNode節點 * @remind 執行editor.setContent方法和執行'inserthtml'命令後,會運行該過濾函數 * @example * ```javascript * editor.filterInputRule(editor.body); * ``` * @see UE.Editor:addInputRule */ filterInputRule: function (root) { // kdy修改 return ; for (var i = 0, ci; ci = this.inputRules[i++];) { ci.call(this, root) } },
ueditor.all.js源碼中9969行的過濾器defaultfilter也直接加入return;
UE.plugins['defaultfilter'] = function () { return; // kdy修改 ......省略 }
ueditor.all.js源碼中17648行,修改video標籤加入咱們自定義屬性t_crc,t_tag
/** * 建立插入視頻字符竄 * @param url 視頻地址 * @param width 視頻寬度 * @param height 視頻高度 * @param align 視頻對齊 * @param toEmbed 是否以flash代替顯示 * @param addParagraph 是否須要添加P 標籤 * // kdy修改 */ function creatInsertStr(url,width,height,id,align,classname,type,node){ let urlJSON = undefined; try { urlJSON = JSON.parse(url); } catch (error) { if (node != undefined) { urlJSON = { "url": node.getAttr("_url"), "crc": node.getAttr("t_crc") }; } } let crc = urlJSON.crc; if(node != undefined){ crc = node.getAttr("t_crc"); } url = urlJSON.url; url = utils.unhtmlForUrl(url); align = utils.unhtml(align); classname = utils.unhtml(classname); width = parseInt(width, 10) || 0; height = parseInt(height, 10) || 0; //修改了這裏 var str; switch (type){ case 'image': str = '<img t_tag="cxUeditorUploadFile" t_crc="'+crc+'" ' + (id ? 'id="' + id+'"' : '') + ' width="'+ width +'" height="' + height + '" _url="'+url+'" class="' + classname.replace(/\bvideo-js\b/, '') + '"' + ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+'" />' break; case 'embed': str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' + ' src="' + utils.html(url) + '" width="' + width + '" height="' + height + '"' + (align ? ' style="float:' + align + '"': '') + ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >'; break; case 'video': var ext = url.substr(url.lastIndexOf('.') + 1); if(ext == 'ogv') ext = 'ogg'; str = '<video t_tag="cxUeditorUploadFile" t_crc="'+crc+'" ' + (id ? ' id="' + id + '"' : '') + ' class="' + classname + ' video-js" ' + (align ? ' style="float:' + align + '"': '') + ' controls preload="none" width="' + width + '" height="' + height + '" src="' + url + '" data-setup="{}">' + '<source src="' + url + '" type="video/' + ext + '" /></video>'; break; } return str; }
ueditor.all.js源碼中17780行,視頻上傳後的回調函數加入t_crc 和 t_tag
me.commands["insertvideo"] = { execCommand: function (cmd, videoObjs, type){ videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs]; var html = [],id = 'tmpVedio', cl; for(var i=0,vi,len = videoObjs.length;i<len;i++){ vi = videoObjs[i]; cl = (type == 'upload' ? 'edui-upload-video video-js vjs-default-skin':'edui-faked-video'); html.push(creatInsertStr( vi.url, vi.width || 420, vi.height || 280, id + i, null, cl, 'image')); } me.execCommand("inserthtml",html.join(""),true); var rng = this.selection.getRange(); for(var i= 0,len=videoObjs.length;i<len;i++){ var img = this.document.getElementById('tmpVedio'+i); domUtils.removeAttributes(img,'id'); rng.selectNode(img).select(); me.execCommand('imagefloat',videoObjs[i].align) } }, queryCommandState : function(){ var img = me.selection.getRange().getClosedNode(), flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1); return flag ? 1 : 0; } };
ueditor.all.js源碼中24536行,修改image標籤圖片上傳成功後的回調函數,這個方法會在富文本編輯框中加入咱們上傳的圖片,一樣加入t_crc 和 t_tag
function callback(){ try{ var link, json, loader, body = (iframe.contentDocument || iframe.contentWindow.document).body, result = body.innerText || body.textContent || ''; json = (new Function("return " + result))(); // 修改這裏 let urlJSON = JSON.parse(json.url); let t_url = urlJSON.url; let t_crc = urlJSON.crc; json.url = t_url; link = me.options.imageUrlPrefix + json.url; if(json.state == 'SUCCESS' && json.url) { loader = me.document.getElementById(loadingId); loader.setAttribute('src', link); loader.setAttribute('_src', link); loader.setAttribute('title', json.title || ''); loader.setAttribute('alt', json.original || ''); loader.setAttribute('style','max-width:650px'); loader.setAttribute('t_crc', t_crc || ''); loader.setAttribute('t_tag','cxUeditorUploadFile'); loader.removeAttribute('id'); domUtils.removeClasses(loader, 'loadingclass'); } else { showErrorLoader && showErrorLoader(json.state); } }catch(er){ showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError')); } form.reset(); domUtils.un(iframe, 'load', callback); }
ueditor.all.js源碼中24812行,上傳附件後的回調函數,一樣加入t_crc 和 t_tag
return { commands:{ 'insertfile': { execCommand: function (command, filelist){ filelist = utils.isArray(filelist) ? filelist : [filelist]; var i, item, icon, title, html = '', URL = me.getOpt('UEDITOR_HOME_URL'), iconDir = URL + (URL.substr(URL.length - 1) == '/' ? '':'/') + 'dialogs/attachment/fileTypeImages/'; for (i = 0; i < filelist.length; i++) { item = filelist[i]; // 修改這裏 let urlJSON = JSON.parse(item.url); let t_url = urlJSON.url; let t_crc = urlJSON.crc; item.url = t_url; icon = iconDir + getFileIcon(item.url); title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1); html += '<p style="line-height: 16px;">' + '<img style="vertical-align: middle; margin-right: 2px;" src="'+ icon + '" _src="' + icon + '" />' + '<a t_crc="'+ t_crc +'" t_tag="cxUeditorUploadFile" style="font-size:12px; color:#0066cc;" href="' + item.url +'" title="' + title + '">' + title + '</a>' + '</p>'; } me.execCommand('insertHtml', html); // me.fireEvent('afterUpfile', filelist); } } } }
完成
連接:https://pan.baidu.com/s/1JZ0qbz7Fu0EL1H5quA98Jg 提取碼:raer