综述
ImageUploader继承于Uploader,用于解决Uploader过于复杂,调用不便的问题,ImageUploader专门用于图片上传,自带图片验证,改进了伪属性配置方式。
ImageUploader的特性
- 支持ajax、flash、iframe三方案,兼容所有浏览器。(iframe不推荐使用)
- 多主题支持,可以自己定制主题
- 支持多选批量上传
- 支持上传进度显示
- 支持取消上传
- 支持图片预览(使用flash上传不支持)
- 支持上传验证
- 多种配置方式
demo汇总
文档内容非常详实,为了方便大家快速使用,将文档中的demo做了提取,即拿即用。
-
简单demo:js配置上传组件
-
简单demo:属性配置上传组件
-
上传验证控制的demo
-
组件全部事件演示
-
渲染默认队列数据的demo
-
图片队列控制的demo
-
只使用flash上传的demo
-
只使用iframe上传的demo
-
常用属性控制
-
常用方法控制
ImageUploader内置的主题
3种方式初始化组件
gallery的包配置是必不可少:
KISSY.config({ packages:[ { name:"gallery", path:"http://a.tbcdn.cn/s/kissy/", charset:"utf-8" } ] });
1.使用js配置初始化组件
KISSY.use('gallery/form/1.3/uploader/imageUploader', function (S, ImageUploader) { new ImageUploader('#J_JsUploaderBtn','#J_JsUploaderQueue',{ // 文件域 name:"Filedata", //处理上传的服务器端脚本路径 action:"upload.php", //用于放服务器端返回的url的隐藏域 urlsInputName:"jsImageUrls" }).render(); })
配置参数说明
参数名 | 类型 | 默认值 | 描述 |
---|---|---|---|
action | String | "" | 服务器端处理上传的路径 |
name | String | Filedata | 文件上传域name名,服务器端通过name来获取和处理上传数据 |
urlsInputName | String | '' | 用于存放服务器端返回的文件路径的input(type="hidden"),当页面内不存在这个input时,组件会自动创建一个 |
2.使用标签属性配置初始化
1) 需要个input标签(type="image-uploader")
属性 | 描述 |
---|---|
type="image-uploader" |
此属性为了配合Butterfly使用,表明此input为图片上传专用组件 |
id="J_UploaderBtn" |
脚本实例化上传组件时使用的钩子 |
name="Filedata" |
非常重要,文件上传域name名,服务器端通过name来获取和处理上传数据 |
value="上传图片" |
上传按钮上的文案 |
2) 创建一个input(hidden)用于存放服务器端返回的url
给上传按钮input加上urlsInputName="imageUrls"
属性,这样当上传成功后图片url会被加入到这个隐藏域中(多个图片路径以逗号隔开)。
3) 创建一个空的图片队列
给上传按钮input加上queueTarget="#J_UploaderQueue"
属性,将上传按钮和上传队列关联起来,当选择完图片后,自动显示图片。
4) 配置服务器端参数
上传组件必须有服务器端脚本配合,所以需要个服务器端路径。可以使用action
属性。
可能你还需要向服务器post一些参数,比如用户名,商品id等,可以使使用postData='{"author":"明河"}'
。
5) demo中完整的html结构
6) 初始化ImageUploader
配置下gallery包路径(为了利用淘宝cdn,可以快速引用butterfly库,所以将代码托管在kissy gallery下)。
var S = KISSY, path = "http://a.tbcdn.cn/s/kissy/"; KISSY.config({ packages:[ { name:"gallery", path:path, charset:"utf-8" } ] });
初始化ImageUploader:
KISSY.use('gallery/form/1.3/uploader/imageUploader', function (S, ImageUploader) { new ImageUploader('#J_UploaderBtn').render(); })
theme
属性时,加载默认主题theme="imageUploader"
,gallery/form/1.3/uploader/themes/imageUploader/index-min.js
和gallery/form/1.3/uploader/themes/imageUploader/style.css
。
与服务器端的交互
服务器端处理异步上传跟同步上传没太大区别,核心的操作是获取前端post到服务器端的数据,比如前端post的文件域name
为Filedata,服务器端处理Filedata内的文件数据即可。
服务器端处理完上传(无论是成功还是失败),需要返回一个json结果集,格式如下:
{"status":1,"data":{"name":"minghe.jpg","url":"www.36ria.com/minghe.jpg"}}
{"status":0,"message":"图片过大!"}
""
,不然json会解析失败。"status":1
,才是上传成功的标识,其他任何状态码都认定为失败。demo php可以看 源码。
urlsInputName
配置的隐藏域内。如何向服务器端post额外的数据?
使用js传参方式,增加post
配置项即可,比如下面的代码:
KISSY.use('gallery/form/1.3/uploader/ImageUploader', function (S, ImageUploader) { var imageUploader = new ImageUploader('#J_UploaderBtn', '#J_UploaderQueue',{ data:{userName:"minghe",email:"minghe36@126.com"}, name:"Filedata", urlsInputName:"fileUrls" }); })
如果是使用属性传参,在input上增加postData
(不是data)属性即可,比如下面代码:
如何通过脚本动态修改post数据?
imageUploader.on('render',function(ev){ var uploader = ev.uploader; uploader.set('data',{userName:"ziying",email:"daxingplay@gmail.com"}) })
通过setdata
属性值来动态修改post到服务器端数据。
如果服务器返回的数据结构不符合解析要求,如何处理呢?
1.3后Uploader新增filter
属性,可以通过这个过滤器,重新map下丢给组件处理的数据。
uploader.set('filter',function(data){ data = S.JSON.parse(data); //unicode自动转换测试 data.author = '\u660e\u6cb3'; return data; })
服务器端如何根据上传类型来做些返回数据的差异处理呢?
典型的使用场景如下:flash上传,服务器返回的中文错误消息,打印到页面中时会乱码,这时候需要服务器端根据上传类型,在flash上传的情况下,将中文打印成unicode的编码,比如明河,输出为\u660e\u6cb3。
组件会自动会post上传方式到服务器端,字段为type
。
如何处理服务器返回的错误消息?
可以监听uploader的error事件,然后处理出错消息,比如下面的代码:
uploader.on('error',function(ev){ var result = ev.result; alert(result.msg); })
IE下上传失败的处理
如果你在使用uploader中遇到IE下进度条不走的情况,多半的原因是由于在域名根目录下没有放跨域策略文件crossdomain.xml
导致的。
以淘宝网的跨域策略为例:
tbcdn.cn为swf文件所在的位置,安全策略文件需要加上。
当不存在crossdomain.xml文件时,控制台会打印错误消息,比如:上传验证控制
var authImageUploader = new ImageUploader('#J_AuthBtn','#J_AuthQueue',{ action:"upload.php", urlsInputName:"authImageUrls" }); authImageUploader.on('render',function(ev){ var uploader = ev.uploader; var max = uploader.get('max'); var required = uploader.get('required'); var allowExts = uploader.get('allowExts'); var maxSize = uploader.get('maxSize'); $('.J_AuthMsg').text('max:'+max + ',required:' + required + ',allowExts:' + allowExts + ',maxSize:' + maxSize); $('#J_TestRequired').on('click',function(ev){ var isPass = uploader.testRequired(); alert(isPass); }); $('#J_TestMax').on('click',function(ev){ var isPass = uploader.testMax(); alert(isPass); }); }); authImageUploader.render();
支持的验证规则
规则名 | 默认值 | 描述 |
---|---|---|
allowExts | jpg,jpeg,png,gif,bmp | 图片格式验证控制,ImageUploader自带此验证。 |
required | true |
必须至少上传一个文件
组件默认不触发,可以使用uploader的testRequired()方法手动验证。
|
max | 3 |
最多上传N个图片,当达到N个图片后按钮会增加禁用样式uploader-button-disabled ,用户可以通过这个样式名定制需要的置灰样式。
可以用uploader.get('max')来获取该配置项值。
|
maxSize | 1024 |
单图片最大允许上传的文件大小,单位是KB
如果是iframe上传方式,此验证无效。
|
allowRepeat | false | 是否允许多次上传同一个文件
不推荐增加这个验证,比较粗糙,只是根据文件名来做重复判断。
|
如何配置验证?
1) 伪属性配置方式:
2) js配置方式:
var authImageUploader = new ImageUploader('#J_AuthBtn','#J_AuthQueue',{ maxSize: 500, max:4, allowExts:"png", required, authMsg:{ max:'每次最多上传{max}个图片!', maxSize:'图片大小为{size},超过{maxSize}!', required:'至少上传一张图片!', require:'至少上传一张图片!', allowExts:'不支持{ext}格式图片!' } });
authMsg用于配置验证消息,一般采用默认的即可。
如何获取和设置验证配置?
想要获取验证配置非常简单,获取uploader对应的属性即可:
authImageUploader.on('render',function(ev){ var uploader = ev.uploader; var max = uploader.get('max'); var required = uploader.get('required'); var allowExts = uploader.get('allowExts'); var maxSize = uploader.get('maxSize'); });
render
事件,然后监听ev.uploader
。设置验证配置,同样简单,使用uploader的set方法,比如uploader.set('max',5)
。
如何在外部验证max和required?
可以使用uploader.testMax()
和uploader.testRequired()
,比如下面的代码:
$('#J_TestRequired').on('click',function(ev){ var isPass = uploader.testRequired(); alert(isPass); }); $('#J_TestMax').on('click',function(ev){ var isPass = uploader.testMax(); alert(isPass); });
监听error出错事件
当验证没有通过时,会触发uploader的error事件,示例代码如下:
uploader.on('error',function(ev){ var rule = ev.rule, msg = ev.msg,status = ev.status; if (rule == 'max') { alert(msg); } if(status === -1){ alert('前端验证错误'); } })
如何渲染默认队列数据?
在实际应用中通常会有个需求:用户已经上传了三张图片,然后保存,那么用户再进入这个页面时,应该如何展示这三张图片呢?
这里有个难点,我们需要把图片插入到组件的队列中,这样文件数的统计、删除等行为才是一致的。
只要开发将图片的url打印到urlsInput隐藏域中即可,组件会自动渲染,比如下面的代码:
如何使用其他主题
使用refundUploader
主题,增加个属性theme="refundUploader"
,该主题是从淘宝退款的上传凭证提炼出来的。
使用js传参方式,加上theme:"refundUploader"
即可。
内置的主题,无法满足实际的需求场景,还可以自制主题,可以看《如何制作属于自己的主题》。
事件演示
ImageUploader支持的所有事件
事件名 | 描述 |
---|---|
select | 选择完文件后触发 |
add | 向队列添加完文件后触发 |
start | 开始上传后触发 |
progress | 正在上传中时触发,这个事件在iframe上传方式中不存在 |
success | 上传成功后触发 |
error | 上传失败后触发 |
cancel | 取消上传后触发 |
restore | 渲染默认队列数据结束后触发 |
remove | 删除队列中的图片后触发 |
statusChange | 队列中的图片上传状态发生改变后触发 |
用法举例
var imageUploader2 = new ImageUploader('#J_UploaderBtn2', '#J_UploaderQueue2'); imageUploader2.on('render', function (ev) { addMsg(ev, '上传组件准备就绪!'); }); imageUploader2.on('select', function (ev) { var files = ev.files; addMsg(ev, '选择了' + files.length + '个文件'); }); imageUploader2.on('start', function (ev) { var index = ev.index, file = ev.file; addMsg(ev, '开始上传,文件名:' + file.name + ',队列索引为:' + index); }); imageUploader2.on('progress', function (ev) { var file = ev.file, loaded = ev.loaded, total = ev.total; addMsg(ev, '正在上传,文件名:' + file.name + ',大小:' + total + ',已经上传:' + loaded); }); imageUploader2.on('success', function (ev) { var index = ev.index, file = ev.file; //服务器端返回的结果集 var result = ev.result; addMsg(ev, '上传成功,服务器端返回上传方式:' + result.type); }); imageUploader2.on('complete', function (ev) { var index = ev.index, file = ev.file; //服务器端返回的结果集 var result = ev.result; addMsg(ev, '上传结束,服务器端返回上传状态:' + result.status); }); imageUploader2.on('error', function (ev) { var index = ev.index, file = ev.file; //服务器端返回的结果集 var result = ev.result; addMsg(ev, '上传失败,错误消息为:' +result.msg); }); imageUploader2.on('add',function(ev){ var queue = ev.queue; var file = ev.file; addMsg(ev, '队列添加文件!文件名为:'+file.name); }); imageUploader2.on('remove',function(ev){ var queue = ev.queue; addMsg(ev, '队列删除文件!文件索引值:'+ev.index); alert('队列中的文件数为:'+queue.get('files').length); }); imageUploader2.render();
所有的事件对象(ev)都带有Uploader和queue的实例,可以通过ev.uploader
和ev.queue
来控制上传和队列。
多选/禁用/立即上传控制
使用js传参的配置方式:
var imageUploader3 = new ImageUploader('#J_UploaderBtn3', '#J_UploaderQueue3',{ autoUpload: false, multiple:false, disabled:true }); imageUploader3.render();
html标签属性配置方式:
disabled="false"
无效接口说明
参数名 | 类型 | 默认值 | 描述 |
---|---|---|---|
autoUpload | Boolean | true | 是否自动上传,当为false 时,可以通过uploader的upload() 和uploadFiles() 手动上传队列中的文件。 |
multiple | Boolean | true | 是否开启多选支持
如果采用iframe上传,请设置为
false |
disabled | Boolean | false | 是否可用,false为按钮可用 |
通过uploader的set方法手动改变这三个状态
用法举例:
imageUploader3.on('render',function(ev){ var uploader = ev.uploader; $('#J_Disabled').on('change',function(ev){ var isChecked = $(ev.target).prop('checked'); uploader.set('disabled',isChecked); }); $('#J_Multiple').on('change',function(ev){ var isChecked = $(ev.target).prop('checked'); uploader.set('multiple',isChecked); }); $('#J_UploadAll').on('click',function(){ uploader.uploadFiles(); }) });
uploadFiles()
方法为上传所有队列中等待的文件。
queue(队列实例)控制
示例
想要操作队列,就必须先获取Queue实例,比如下面的代码:
//uploaderQueueTest为RenderUploader的实例 uploaderQueueTest.on('render',function(ev){ var queue = ev.queue; });
下面举例说明常用的方法和属性。
add():向队列添加文件
$('#J_Add').on('click', function (ev) { //测试文件数据 var testFile = {'name':'test.jpg', 'size':2000, 'input':{}, 'file':{'name':'test.jpg', 'type':'image/jpeg', 'size':2000} }; //向队列添加文件 var file = queue.add(testFile); S.log('添加的文件数据为:'+file); });
remove():删除队列中的文件
$('#J_DelFirst').on('click', function (ev) { var removeFile = queue.remove(0); S.log('删除的文件数据为:'+removeFile); });
fileStatus(index, status, args):改变文件状态
默认的主题共有以下文件状态:'waiting'、'start'、'progress'、'success'、'cancel'、'error'
不同的主题拥有的状态情况可能存在差异。
$('#J_ChangeStatus').on('click', function (ev) { queue.fileStatus(0, 'success'); });
clear():删除队列内的所有文件
$('#J_Clear').on('click', function (ev) { queue.clear(); });
files:通过该属性可以获取队列中所有的文件数据
$('#J_GetAll').on('click', function (ev) { var ids = [], files = queue.get('files'); S.each(files, function (file) { ids.push(file.id); }); alert('所有文件id:' + ids); });
getFiles(type):获取指定状态下的文件
$('#J_GetStatusFileIds').on('click', function (ev) { var files = queue.getFiles('waiting'), ids = []; S.each(files, function (file) { ids.push(file.id); }); alert('所有等待中的文件id为:' + ids); });
getIndexs(type):获取等指定状态的文件对应的文件数组索引值组成的数组
getFiles()和getFileIds()的作用是不同的,getFiles()类似过滤数组,获取的是指定状态的文件数据,而getFileIds()只是获取指定状态下的文件对应的在文件数组内的索引值。
$('#J_GetStatusFilesIndex').on('click', function () { var indexs = queue.getIndexs('waiting'); alert('所有等待中的文件index为:' + indexs); })
uploader常用方法
upload (index)
上传指定队列索引的文件。
//上传队列中的第一个文件,uploader为Uploader的实例 uploader.upload(0)
uploadFiles (status)
批量上传队列中的指定状态下的文件。
//上传队列中所有等待的文件 uploader.uploadFiles("waiting")
cancel (index)
取消文件上传,当index参数不存在时取消当前正在上传的文件的上传。cancel并不会停止其他文件的上传(对应方法是stop)。
//取消当前正在上传的文件的上传 uploader.cancel();
stop():停止上传动作
//停止上传 uploader.stop();
testMax():验证图片是否已经达到最大允许上传数
//return false | true; uploader.testMax();
testRequired():验证是否至少上传了一个文件
//return false | true; uploader.testRequired();
uploader常用属性/配置
uploader的配置都会写入成uploader的属性内。uploader的几个关键配置前面都有提到了,这里做个汇总。
属性名 | 类型 | 默认值 | 是否只读 | 描述 |
---|---|---|---|---|
type
不推荐使用
|
String|Array | "auto" | 只读 | 采用的上传方案,当值是数组时,比如“type” : ["flash","ajax","iframe"],按顺序获取浏览器支持的方式,该配置会优先使用flash上传方式,如果浏览器不支持flash,会降级为ajax,如果还不支持ajax,会降级为iframe;当值是字符串时,比如“type” : “ajax”,表示只使用ajax上传方式。这种方式比较极端,在不支持ajax上传方式的浏览器会不可用;
当“type” : “auto”,auto是一种特例,等价于["ajax","flash","iframe"]。
不再推荐配置type,除非在使用flash时遇到难以解决的问题。
|
curUploadIndex | Number | "" | 只读 | 当前上传的文件对应的在数组内的索引值,如果没有文件正在上传,值为空 |
isAllowUpload | Boolean | true | 只读 | 是否允许上传文件 |
queue | Queue | '' | 只读 | Queue队列的实例,想要对队列进行操作或监听队列的事件,就必须先获取这个属性 |
restoreHook | String | '' | 只读 | 已经存在的文件数据待提取的容器钩子,用法请看默认数据展现 |
autoUpload | Boolean | true | 读/写 | 是否自动上传,当为false 时,可以通过uploader的upload() 和uploadFiles() 手动上传队列中的文件。 |
multiple | Boolean | true | 读/写 | 是否开启多选支持
如果采用iframe上传,请设置为
false |
multipleLen | Number | -1 | 读/写 | 用于限制多选文件个数,值为负时不设置多选限制(v1.2.6+) |
disabled | Boolean | false | 读/写 | 是否可用,false为按钮可用 |
serverConfig
弃用
|
Object | {action:'', data:{}, dataType:'json'} | 读/写 | 服务器端配置,包括最重要的action (路径)配置,data 为post到服务器端数据
|
action | String | '' | 读/写 | 服务器端处理上传的路径(v1.3.0+) |
data | Object | {} | 读/写 | 此配置用于动态修改post给服务器的数据,会覆盖serverConfig的data配置(v1.2.6+) |
name | String | Filedata | 只读 | 文件上传域name名 |
urlsInputName | String | '' | 只读 | 用于存放服务器端返回的文件路径的input(type="hidden") |
max | Number | 3 | 读/写 | 最多上传N张图片,没有配置该项验证时不存在(v1.3.0+) |
maxSize | Number | 1024 | 读/写 | 单文件最大允许上传的文件大小,单位是KB ,没有配置该项验证时不存在(v1.3.0+)
|
required | Boolean | false | 读/写 | 必须至少上传一个文件,没有配置该项验证时不存在(v1.3.0+) |
allowExts | String | 'jpg,jpeg,png,gif,bmp' | 读/写 | 文件格式验证,没有配置该项验证时不存在(v1.3.0+) |
allowRepeat | Boolean | false | 读/写 | 是否允许多次上传同一个文件,没有配置该项验证时不存在(v1.3.0+) |