UEditor是由百度web前端研發部開發所見即所得富文本web編輯器,具有輕量,可定制,注重用戶體驗等特點,開源基於MIT協議,允許自由使用和修改代碼。(抄的...)
UEditor是非常好用的富文本web編輯器,而且全中文API和注釋,方便學習和使用。特別是圖片上傳查看及塗鴉功能極為喜歡,但是有很多情況我們並不需要Web編輯器,而只需要圖片上傳。那么問題來了,提取圖片上傳哪家強.....
網上有很多圖片上傳的控件、插件。但都不是那么的完美,有的只有一張圖片上傳不包含批量上傳,有的沒有圖片查看功能,還有的必須要flash的支持(ios系統就悲劇了),當然還有的不能跨語言,還有上傳沒有狀態顯示,當然還有客戶體驗不是太好, 瀏覽器兼兼容問題就更多了,在線塗鴉更是少之又少。而UEditor上傳圖片幾乎解決了以上的問題。
廢話不多說,走起。
一、從官網(http://ueditor.baidu.com/website/download.html)上下載UEditor選擇開發版[1.4.2 .Net 版本],1、因為本人.Net。2、老的版本更穩定,新版本不支持ie8以下版本。關於其他語言的開發其實和.Net一樣,主要是思路。
二、按照官網的說明文檔(http://fex-team.github.io/ueditor/)把UEditor部署到VS(http://fex-team.github.io/ueditor/#server-net)中,保證UEditor可以正常使用,特別是圖片上傳功能。本文主要講解單獨提取UEditor圖片上傳功能,所以對UEditor的使用部署請參考官網(http://ueditor.baidu.com)。圖是本人在VS中的目錄結構。
三、修改config.json相關配置信息,這個配置主要關於上傳以及查看圖片的相關配置。
四、修改ueditor.config.js中的toolbars以及serverUrl ,我們只顯示多圖片單圖片以及塗鴉的顯示。
// 服務器統一請求接口路徑 , serverUrl: URL + "../../Common/controller.ashx" //工具欄上的所有的功能按鈕和下拉框,可以在new編輯器的實例時選擇自己需要的從新定義 , toolbars: [[ 'insertimage', 'scrawl', 'simpleupload' ]]
五、我們的主要內容是創建自己的通用提取上傳圖片的js文件(custom.js)和簡單修改UEditor的ueditor.all.js文件。
1)、我們在頁面中添加UEditor顯示Div[editor-img]以及我們后面要處理上傳完以后處理文件的名稱[temp-img-list],還有初始化Ueditor。
$("body").append(" <div id=\"editor-img\" style=\"display:none\"></div><div id=\"temp-img-list\" style=\"display: none\"></div>"); var ue = UE.getEditor('editor-img');
2)、我們可以把div id='editor-img'的display='block'顯示,然后我們就可以在頁面看到完整的包含圖片上傳多圖片上傳以及塗鴉的UEditor了。
3)、我們在頁面Default.aspx中定義一個多圖片上傳按鈕a標簽,然后調用uploadImgs()方法,我們要做的就是點擊a標簽觸發UEditor多圖片上傳按鈕,我們查看源碼可以到多圖片上傳按鈕的div class 為edui-for-insertimage,如圖。然后我們點擊a標簽就彈出圖片上傳的窗口了。
function uploadImgs() { $(".edui-for-insertimage .edui-button-body")[0].click(); }
我們這時可以上傳圖片以及在線查看圖片了。然后點擊確認。。。。。。我們這時點擊確認會發現會把圖片加載到UEditor中,這並不是我們想要的,我們已經完成把圖片上傳到服務器了,現在只要知道我們上傳了哪些圖片或者查看圖片時選擇了哪些圖片的名稱就完成我們所需要的了。
4)、當點擊確認時圖片加載到編輯器中,編輯器的內容就會發生變化。我們可以監聽編輯器內容的變化然后再獲取編輯器中的內容進行分析處理即可獲取圖片名稱。我們查看官方API可以找到contentChange事件(編輯器內容發生改變時會觸發該事件),然后監聽此事件。由於單個圖片上傳相比批量上傳和塗鴉比較復雜,我們稍后再做詳解。
UE.getEditor('editor-img').addListener('contentChange', function (editor) { //獲取編輯器中的內容(html 代碼) var img = UE.getEditor('editor-img').getPlainTxt(); if (img != "") { //把編輯器中的內容放到臨時div中,然后進行獲取文件名稱。 $("#temp-img-list").html(img); var array = new Array(); //循環獲取文件名稱 $("#temp-img-list img").each(function () { var src = $(this).attr("src"); var name = src.replace("/upload/image/", ""); array.push(name); }); //清空編輯器中的內容,以便下一次添加圖片。 UE.getEditor('editor-img').execCommand('cleardoc'); //調用callbackImg獲取懂圖片名稱 if (typeof callbackImg === "function") { eval("callbackImg('" + array + "')"); } } });
5)、我們自定義js方法callbackImg就可以獲取到圖片名稱了
function callbackImg(imgName) { var names = imgName.split(","); for (var i = 0; i < names.length; i++) { $("#show-img-name").append($("<div></div>").html($("<a></a>").html(names[i]).attr("href", "/upload/image/" + names[i] + "").attr("target", "_blank"))); } }
6)、這樣一個完整的批量圖片上傳查看的功能就完成了。同理我們可以添加塗鴉的功能,其實這這一步塗鴉的功能只要一步即可,自定義一個js方法insertScrawl(),然后調用insertScrawl即可完成塗鴉的功能。
function insertScrawl() { $('.edui-for-scrawl .edui-button-body')[0].click(); }
到此為止,我們就完成了批量圖片上傳和塗鴉功能。
六、通讀代碼其實發現批量圖片上傳和塗鴉就是簡單的模擬按鈕調用,然后上傳完圖片或者選擇完圖片然后點擊確認回調處理編輯器中的內容獲取文件名稱。但是單獨上傳圖片會有一定的復雜度。
1)、我們用UEditor上傳單個圖片時會發現在編輯器中會有個等待的圖片,當圖片上傳完畢以后會把等待圖片換成我們上傳的圖片。
上傳中...
上傳完成以后。
2)、那么問題又來了,問題一,我們原來是監聽編輯器中文本變化,然后獲取其中的圖片提取名稱,這時我們獲取的是等待的圖片而不是我們真正上傳的圖片。問題二,這時上傳並沒有狀態顯示,如果圖片過大或者網速不是很好的情況下,導致用戶體驗不是很好。
解決這些問題我們首先要找到圖片剛開始上傳和上傳完畢的事件,還有要判斷編輯器中的圖片是否是等待的圖片,反之就是我們上傳的圖片。
1)、查找源碼我們可以在ueditor.all.js中找到上傳開始和上傳完成的事件,分別在24379行和24390行,在ueditor.all.js中分別調用js方法preUploadSingleImg()和uploadSingleImgCallback()。
2)、ueditor.all.js中修改代碼(1,2,3行,23,24,25行)
if (typeof preUploadSingleImg === "function") {
preUploadSingleImg();
}
function callback() {
try{
var link, json, loader,
body = (iframe.contentDocument || iframe.contentWindow.document).body,
result = body.innerText || body.textContent || '';
json = (new Function("return " + result))();
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.removeAttribute('id');
domUtils.removeClasses(loader, 'loadingclass');
} else {
showErrorLoader && showErrorLoader(json.state);
}
//單獨提取上傳回調函數。
if (typeof uploadSingleImgCallback === 'function') {
uploadSingleImgCallback();
}
3)、在自定義js custom.js中添加方法
//單傳圖片開始上傳,顯示等待。 function preUploadSingleImg() { if ($("#loading").length > 0) { $("#loading").html("<img src='/Scripts/ueditor/loading.gif'>");; } } //單傳圖片回調,隱藏等待圖片 function uploadSingleImgCallback() { if ($("#loading").length > 0) { $("#loading").empty(); } }
4)、最后要做的就是在頁面上添加一個空的div id='loading'
5)、這樣我們就解決了單獨圖片上傳狀態的問題,但是還有一個獲取編輯器中上傳圖片的問題,這時要做兩步,
1)、在custom.js中修改代碼,編輯器內容改變事件中contentChange 判斷是否是等待圖片,如果是等待圖片我們不做任何的處理即可。修改代碼為
UE.getEditor('editor-img').addListener('contentChange', function (editor) { //獲取編輯器中的內容(html 代碼) var img = UE.getEditor('editor-img').getPlainTxt(); if (img != "") { //判斷是否是單圖片上傳,如果是單傳不做任何處理,等待回調函數再次調用。 if (img.indexOf("loadingclass") == -1) { //把編輯器中的內容放到臨時div中,然后進行獲取文件名稱。 $("#temp-img-list").html(img); var array = new Array(); //循環獲取文件名稱 $("#temp-img-list img").each(function () { var src = $(this).attr("src"); var name = src.replace("/upload/image/", ""); array.push(name); }); //清空編輯器中的內容,以便下一次添加圖片。 UE.getEditor('editor-img').execCommand('cleardoc'); //調用callbackImg獲取懂圖片名稱 if (typeof callbackImg === "function") { eval("callbackImg('" + array + "')"); } } } });
2)、我們在上傳完事件中清空編輯器中的內容,然后編輯器又會調用 contentChange 事件,由於上傳完畢以后編輯器中不是等待的圖片而是我們真正上傳的圖片,這時只要按照多圖片上傳獲取圖片名稱即可。修改方法uploadSingleImgCallback為
//單傳圖片回調,然后清理內容,在清理內容會自動調用contentChange事件,然后再獲取上傳文件的文件名。 function uploadSingleImgCallback() { UE.getEditor('editor-img').execCommand('cleardoc'); if ($("#loading").length > 0) { $("#loading").empty(); } }
6)、最后我自定義一個按鈕調用方法uploadImg()即可彈出窗口選擇圖片,然后選擇圖片點擊確定即可上傳到服務器並獲取到文件名稱。
function uploadImg() { $(".edui-for-simpleupload input").click(); }
總結:我們選擇就從UEditor中提取了多圖片單圖片上傳以及塗鴉的功能。關於其他語言,邏輯一樣的,只要更換不同的服務端代碼即可。
以下為動畫演示
謝謝觀賞...
Github:https://github.com/Emrys5/UeditorFileUpload