做了個文章編輯頁面,用了百度的UEditor,文章編輯上傳圖片毫無問題,但是封面圖上傳又開始頭疼了,想調用UEditor那個單圖片上傳的按鈕功能,但是js這塊實在沒深入研究過,先放下,找找網上可否有解決方案,方案倒是有,但基本都是出自同一源頭,方法都是再創建一個實例然後隱藏再調用的思路,總是覺得不爽,算了照做,但是彈出來是多圖的對話框,還有其他問題,這不能忍,必須自己幹!具體如下:
直接定位UEditor的代碼文件夾找到 ueditor.all.js
因爲修改了該文件,在項目中需要引用ueditor.all.min.js的地方替換成ueditor.all.js
UEditor版本1.4.3.3,定位到行24462(或者直接查找 simpleupload,即可找到),這是單圖上傳的插件代碼,將整個插件代碼替換爲下面的代碼
UE.plugin.register('simpleupload', function (){
var me = this,
isLoaded = false,
containerBtn;
function initUploadBtn() {
var w = containerBtn.offsetWidth || 20,
h = containerBtn.offsetHeight || 20,
btnIframe = document.createElement('iframe'),
btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;';
domUtils.on(btnIframe, 'load', function () {
var timestrap = (+new Date()).toString(36),
wrapper,
btnIframeDoc,
btnIframeBody;
btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document);
btnIframeBody = btnIframeDoc.body;
wrapper = btnIframeDoc.createElement('div');
wrapper.innerHTML = '<form id="edui_form_' + timestrap + '" target="edui_iframe_' + timestrap + '" method="POST" enctype="multipart/form-data" action="' + me.getOpt('serverUrl') + '" ' +
'style="' + btnStyle + '">' +
'<input id="edui_input_' + timestrap + '" type="file" accept="image/*" name="' + me.options.imageFieldName + '" ' +
'style="' + btnStyle + '">' +
'</form>' +
'<iframe id="edui_iframe_' + timestrap + '" name="edui_iframe_' + timestrap + '" style="display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;"></iframe>';
wrapper.className = 'edui-' + me.options.theme;
wrapper.id = me.ui.id + '_iframeupload';
btnIframeBody.style.cssText = btnStyle;
btnIframeBody.style.width = w + 'px';
btnIframeBody.style.height = h + 'px';
btnIframeBody.appendChild(wrapper);
if (btnIframeBody.parentNode) {
btnIframeBody.parentNode.style.width = w + 'px';
btnIframeBody.parentNode.style.height = w + 'px';
}
var form = btnIframeDoc.getElementById('edui_form_' + timestrap);
var input = btnIframeDoc.getElementById('edui_input_' + timestrap);
var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap);
domUtils.on(input, 'change', function () {
if (!input.value) return;
var loadingId = 'loading_' + (+new Date()).toString(36);
var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';
var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));
var allowFiles = me.getOpt('imageAllowFiles');
me.focus();
me.execCommand('inserthtml', '<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme + '/images/spacer.gif" title="' + (me.getLang('simpleupload.loading') || '') + '" >');
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);
}
} catch (er) {
showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));
}
form.reset();
domUtils.un(iframe, 'load', callback);
}
function showErrorLoader(title) {
if (loadingId) {
var loader = me.document.getElementById(loadingId);
loader && domUtils.remove(loader);
me.fireEvent('showmessage', {
'id': loadingId,
'content': title,
'type': 'error',
'timeout': 4000
});
}
}
/* 判斷後端配置是否沒有加載成功 */
if (!me.getOpt('imageActionName')) {
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
// 判斷文件格式是否錯誤
var filename = input.value,
fileext = filename ? filename.substr(filename.lastIndexOf('.')) : '';
if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
showErrorLoader(me.getLang('simpleupload.exceedTypeError'));
return;
}
domUtils.on(iframe, 'load', callback);
form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?' : '&') + params);
form.submit();
});
var stateTimer;
me.addListener('selectionchange', function () {
clearTimeout(stateTimer);
stateTimer = setTimeout(function () {
var state = me.queryCommandState('simpleupload');
if (state == -1) {
input.disabled = 'disabled';
} else {
input.disabled = false;
}
}, 400);
});
isLoaded = true;
});
btnIframe.style.cssText = btnStyle;
containerBtn.appendChild(btnIframe);
me.fireEvent('simpleupload_ready'); /* TY Added For Extra Custom SimpleUpload */
}
/*============== TY Added For Extra Custom SimpleUpload =================*/
function BindCustomBtn() {
var w = containerBtn.offsetWidth || 20,
h = containerBtn.offsetHeight || 20,
btnIframe = document.createElement('iframe'),
btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;';
domUtils.on(btnIframe, 'load', function () {
var timestrap = (+new Date()).toString(36),
wrapper,
btnIframeDoc,
btnIframeBody;
btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document);
btnIframeBody = btnIframeDoc.body;
wrapper = btnIframeDoc.createElement('div');
wrapper.innerHTML = '<form id="edui_form_' + timestrap + '" target="edui_iframe_' + timestrap + '" method="POST" enctype="multipart/form-data" action="' + me.getOpt('serverUrl') + '" ' +
'style="' + btnStyle + '">' +
'<input id="edui_input_' + timestrap + '" type="file" accept="image/*" name="' + me.options.imageFieldName + '" ' +
'style="' + btnStyle + '">' +
'</form>' +
'<iframe id="edui_iframe_' + timestrap + '" name="edui_iframe_' + timestrap + '" style="display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;"></iframe>';
wrapper.className = 'edui-' + me.options.theme;
wrapper.id = me.ui.id + '_iframeupload';
btnIframeBody.style.cssText = btnStyle;
btnIframeBody.style.width = w + 'px';
btnIframeBody.style.height = h + 'px';
btnIframeBody.appendChild(wrapper);
if (btnIframeBody.parentNode) {
btnIframeBody.parentNode.style.width = w + 'px';
btnIframeBody.parentNode.style.height = w + 'px';
}
var form = btnIframeDoc.getElementById('edui_form_' + timestrap);
var input = btnIframeDoc.getElementById('edui_input_' + timestrap);
var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap);
domUtils.on(input, 'change', function () {
if (!input.value) return;
var loadingId = 'loading_' + (+new Date()).toString(36);
var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';
var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));
var allowFiles = me.getOpt('imageAllowFiles');
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) {
me.fireEvent('simpleupload_customcomplete', containerBtn.id, link, json.title || '', json.original || '');
} else {
showErrorLoader && showErrorLoader(json.state);
}
} catch (er) {
showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));
}
form.reset();
domUtils.un(iframe, 'load', callback);
}
function showErrorLoader(title) {
if (loadingId) {
me.fireEvent('showmessage', {
'id': loadingId,
'content': title,
'type': 'error',
'timeout': 4000
});
}
}
/* 判斷後端配置是否沒有加載成功 */
if (!me.getOpt('imageActionName')) {
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
// 判斷文件格式是否錯誤
var filename = input.value,
fileext = filename ? filename.substr(filename.lastIndexOf('.')) : '';
if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {
showErrorLoader(me.getLang('simpleupload.exceedTypeError'));
return;
}
domUtils.on(iframe, 'load', callback);
form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?' : '&') + params);
form.submit();
});
var stateTimer;
me.addListener('selectionchange', function () {
clearTimeout(stateTimer);
stateTimer = setTimeout(function () {
var state = me.queryCommandState('simpleupload');
if (state == -1) {
input.disabled = 'disabled';
} else {
input.disabled = false;
}
}, 400);
});
isLoaded = true;
});
btnIframe.style.cssText = btnStyle;
containerBtn.appendChild(btnIframe, containerBtn);
}
/*=======================================================================*/
return {
bindEvents:{
'ready': function() {
//設置loading的樣式
utils.cssRule('loading',
'.loadingclass{display:inline-block;cursor:default;background: url(\''
+ this.options.themePath
+ this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' +
'.loaderrorclass{display:inline-block;cursor:default;background: url(\''
+ this.options.themePath
+ this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' +
'}',
this.document);
},
/* 初始化簡單上傳按鈕 */
'simpleuploadbtnready': function(type, container) {
containerBtn = container;
me.afterConfigReady(initUploadBtn);
},
/*============== TY Added For Extra Custom SimpleUpload =================*/
'simpleupload_custominit': function (type,container) {
containerBtn = container;
BindCustomBtn();
}
/*=======================================================================*/
},
outputRule: function(root){
utils.each(root.getNodesByTagName('img'),function(n){
if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) {
n.parentNode.removeChild(n);
}
});
},
commands: {
'simpleupload': {
queryCommandState: function () {
return isLoaded ? 0:-1;
}
}
}
}
});
插件新增了3個消息,simpleupload_ready、simpleupload_custominit和simpleupload_customcomplete,和新增了一個BindCustomBtn()函數和對應響應消息simpleupload_custominit的處理函數.
simpleupload_ready消息是UEditor初始化綁定單圖上傳按鈕完成發出的消息,響應這個消息開始綁定自己的單圖上傳按鈕
simpleupload_custominit消息是通知UEditor調用BindCustomBtn()綁定自定義的按鈕
simpleupload_customcomplete消息是自定義按鈕上傳圖片完成後會出發的消息,會帶來上傳的結果包括id(自定義按鈕)、link、title、alt參數。
id參數就是自定義按鈕的id,這個可以用來區分是哪個自定義按鈕上傳完畢出發的,也就是說可以支持多個自定義按鈕獨立單圖上傳。
下面是頁面實現一個自定義上傳按鈕(區域)的代碼
頁面部分Html代碼(Div作爲自定義按鈕)
<div id="upload-cover" style="width: 45px; height: 30px; margin-left: 60px; border: 1px solid #808080">
<img id="cover-img" src="" width="45" height="30" style="position: absolute" />
</div>
頁面js代碼
//UEditor And CustomSimpleUpload Init
var ue = UE.getEditor('content');
ue.addListener('simpleupload_ready', function (types) {
var btnUpload = document.getElementById('upload-cover');
ue.fireEvent('simpleupload_custominit', btnUpload);
});
ue.addListener('simpleupload_customcomplete', function (types, id, link, title, alt) {
document.getElementById('cover-img').src = link;
document.getElementById('cover').value = link;//賦值表單的一個隱藏input
});
以上代碼基本上就解決調用單圖上傳的問題,有個問題需要注意下,原單圖的插件是在上傳點擊按鈕(區域)上覆蓋了一層同樣大小的透明按鈕,上傳點擊按鈕的動作觸發的其實是這個透明按鈕,
自定義按鈕按照上面js代碼綁定消息後,觸發方式不變,所以如果點擊無效的話,那應該是透明按鈕沒有重疊到你自己的自定義按鈕上。在插件代碼的函數BindCustomBtn()中,找到
filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;
把透明改爲不透明,自己調整下按鈕位置,和自己的自定義按鈕重疊就OK了。
最終完成效果是這樣的:
1、上傳封面圖片前
2、上傳中
3、上傳完成