最近在用TinyMce做网页编辑器的时候,发现一个很纠结的问题 ,上传图片的时候只能一张一张上传 ,本着懒人不做重复事情的原则,于是想着怎么可以修改一下工具的js代码可以实现一次性上传多图片的目的,话不多说,先看效果:
选择中文件打开后会上传操作,上传成功后会讲图片插入到编辑器:
说说步骤吧:
c = yg({
dom: {
tag: "input",
attributes: {
type: "file",
accept: "image/*",
//这里为file控件添加multiple属性
multiple: "multiple"
},
styles: {
display: "none"
}
},
behaviours: Lu([Fm("input-file-events", [hr(So())])])
})
oe = function(a, u, c, l) {
var t, e = l.getData();
l.block("Uploading image"),
//e..fileinput 是选中的所有文件对象集合
(t = e.fileinput,
0 === t.length ? w.none() : w.some(t[0])).fold(function() {
l.unblock()
},
//这个函数即是上传文件的主要方法
function(n) {
var r = s.URL.createObjectURL(n)
, i = Xt({
url: u.url,
basePath: u.basePath,
credentials: u.credentials,
handler: u.handler
})
, o = function() {
l.unblock(),
s.URL.revokeObjectURL(r)
};
dt(n).then(function(t) {
var e = a.createBlobCache(n, r, t);
i.upload(e).then(function(t) {
l.setData({
src: {
value: t,
meta: {}
}
}),
l.showTab("general"),
re(a, u, c, l),
o()
})["catch"](function(t) {
o(),
a.alertErr(l, t)
})
})
})
}
问题出在这句代码上:0 === t.length ? w.none() : w.some(t[0]),当多个文件时,只是上传第一个文件。所以我们需要修改一下这里面的逻辑,w.some会返回一个对象:
i = {
fold: function(t, e) {
//这里会直接调用传入的第二个匿名函数e,并且将元素传入作参数
return e(n)
},
is: function(t) {
return n === t
},
isSome: h,
isNone: g,
getOr: t,
getOrThunk: t,
getOrDie: t,
getOrNull: t,
getOrUndefined: t,
or: e,
orThunk: e,
map: function(t) {
return b(t(n))
},
ap: function(t) {
return t.fold(y, function(t) {
return b(t(n))
})
},
each: function(t) {
t(n)
},
bind: r,
flatten: t,
exists: r,
forall: r,
filter: function(t) {
return t(n) ? i : v
},
equals: function(t) {
return t.is(n)
},
equals_: function(t, e) {
return t.fold(g, function(t) {
return e(n, t)
})
},
toArray: function() {
return [n]
},
toString: function() {
return "some(" + n + ")"
}
};
里面的fold方法接收两个参数,即传入的两个匿名函数,e参数即可以运行第二个传入的匿名函数,这个函数就是具体的上传方法了。现在我们需要更改一下fold函数的逻辑,把w.some直接传入文件数组 t,然后在fold函数中做逻辑判断,同时对fold函数添加一个匿名方法,以便不该原来的逻辑,只是做多文件上传的变更,看代码:
fold: function(t, e, s) {
if(1===n.length)
{
//如果只有一个文件,则调用原来的逻辑处理
return e(n[0]);
}else{
//如果是多文件,则调用我们自己的逻辑处理
return s(n);
}
}
oe = function(a, u, c, l) {
var t, e = l.getData();
l.block("Uploading image");
(t = e.fileinput,
0 === t.length ? w.none() : w.some(t)).fold(function() {
l.unblock()
},
//原来的上传文件处理逻辑
function(n) {
var r = s.URL.createObjectURL(n)
, i = Xt({
url: u.url,
basePath: u.basePath,
credentials: u.credentials,
handler: u.handler
})
, o = function() {
l.unblock(),
s.URL.revokeObjectURL(r)
};
dt(n).then(function(t) {
var e = a.createBlobCache(n, r, t);
i.upload(e).then(function(t) {
l.setData({
src: {
value: t,
meta: {}
}
}),
l.showTab("general"),
re(a, u, c, l),
o()
})["catch"](function(t) {
o(),
a.alertErr(l, t)
})
})
},
//添加的多文件处理逻辑
//k为多文件的列表信息
function(k) {
var index = 0;
//上传文件时会对文件进行异步编码并且异步上传
//上传单文件不会有什么问题
//但是上传多文件同时上传,因为异步问题,原来的操作方式会上传同一个文件(最后一个文件)
//所以采用服务器返回上传成功了,然后再次调用函数的方式进行队列上传
var upload = function(n) {
var r = s.URL.createObjectURL(n)
, i = Xt({
url: u.url,
basePath: u.basePath,
credentials: u.credentials,
handler: u.handler
})
, o = function() {
l.unblock(),
s.URL.revokeObjectURL(r)
};
dt(n).then(function(t) {
var e = a.createBlobCache(n, r, t);
i.upload(e).then(function(t) {
//上传成功后创建img元素并进行插入
var img = editor.dom.createHTML('img', {
src: t
});
//插入内容
editor.insertContent(img);
//判断是否已经上传完,如果上传完所有文件,则关闭正在上传的操作层
if (++index === k.length) {
o();
} else { //否则继续上传
upload(k[index]);
}
})["catch"](function(t) {
o(),
a.alertErr(l, t)
})
})
}
//对首次调用上传进行验证
if (index < k.length) {
upload(k[index]);
}
})
}
这样基本的工作就做完了 ,后台的上传处理逻辑这边就不贴代码了。还有需要注意的一点是:多图片上传成功一个后插入img元素到编辑器的操作 ,editor本身没有申明,因为组件采用的是严格代码模式,所以需要在插件的最前面申明变量editor,然后在插件调用时对editor进行赋值:
!function me() {
u.add("image", function(t) {
// 对editor进行赋值
editor=t;
fe(t),
de(t),
le(t)
})
}()
差不多这样就完成了。第一次写博客,很多说的不是很清楚,大家不要见怪,稍后我把修改后的代码帖上,大家有需要就看一看 。如果有错误的地方也请大家海涵!