做了个文章编辑页面,用了百度的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、上传完成