最近在做项目中用到了plupload插件,这里简单记录下个人在项目中遇到的一些坑及解决方法。
1.关于兼容性
plupload可以支持到ie6,由于考虑到兼容性,所以选择了plupload,会根据html5,flash,silverlight,html4逐层退化
2.browse_button点击失效
可能有些用户遇到过这种情况,我也遇到了,我的情况是,browse_button的container隐藏了,导致runtime为flash出现报错,所以确保你的container可见
3.多个browse_button问题
产品提了这个需求,用户添加了一些图片,然后想继续添加,如果browse_button不变(位置)没事,而我遇到的是,继续添加按钮是在跟随已添加图片的后面,一开始觉得so easy,在事件FilesAdded重新设置选项browse_button,结果发现,之前添加的文件队列丢了,也就是相当于plupload执行了refresh,重新搞,我想到将原来的browse_button移过来,文件没丢失,在runtime为html5时,效果不错。把代码提交上去,然后测试mm给我提了一个bug,说在ie6,7,8,9继续添加无效,倒腾了一个虚拟机装上ie6,还真不管用,去网上找解决方案,然并卵,并没有找到。只能自己琢磨了,在页面上乱点一通,结果发现点击原来的browse_button的位置可以弹出文件选择框,想把plupload生成的object标签移过来,还是没有用,利用dom查看,发现object相对于container绝对定位,问题的点找到了,可以监控文件队列长度,然后修改object标签的位置,搞定。
vm.uploadPhotoList.$watch('length',function(len){ if(vm.currentRuntime == 'flash'){ var hot_zone = $('.moxie-shim'); if(hot_zone.length>0){ hot_zone.css({140,height:180}); if(len<5){ hot_zone.css({left:168*len,top:70}); }else if(len < 9){ hot_zone.css({left:168*(len-5),top:276}); } } } });
4.预览图片
之前也调研过,预览图片可能会使用到canvas,或者使用datauri(支持ie7+),ie6怎么办,plupload中的moxie有个embed有如下描述
shim object (Flash or SilverLight - very rare, used for legacy browsers that do not have canvas or proper dataURI support,有了这句话,依据网上搜到的代码示例,写下了如下代码
var preloader = new mOxie.Image(); preloader.onload = function() { this.embed('pic_'+file.id, { 138, height: 147, crop:true }); }; preloader.onembedded = function(){ this.destroy(); }; preloader.onerror = function(){ this.destroy(); }; preloader.load(file.getSource());
由于我的电脑是ie11,调试界面可以调整ie版本,自己的代码跑了一下,竟然连ie5都兼容,觉得好开心,把代码提交上去,然后测试mm说你的这个在ie6上怎么没有预览图片啊,我说不可能啊,我的ie5都支持,我自己在虚拟机跑了一下,卧槽,还真不行。查看ie5下的dom结构,用的是datauri,好吧,看来ie的模拟版本不太可靠啊。去网上找解决方案,资料很少,并没有什么有用的(我用的是google),去plupload的官方网站http://www.plupload.com看了一下它的demo,看到ui版本自带预览图选项,需要添加如下代码
1 resize : { 2 width : 200, 3 height : 200, 4 quality : 90, 5 crop: true // crop to exact dimensions 6 }, 7 8 // Views to activate 9 views: { 10 list: true, 11 thumbs: true, // Show thumbs 12 active: 'thumbs' 13 },
我并不想引入jquery ui,因为太大了,然后去看它的源码,有了些眉目
1 function preloadThumb(file, cb) { 2 var img = new o.Image(); 3 4 img.onload = function() { 5 var thumb = $('#' + file.id + ' .plupload_file_thumb', self.filelist).html(''); 6 this.embed(thumb[0], { 7 self.options.thumb_width, 8 height: self.options.thumb_height, 9 crop: true, 10 swf_url: o.resolveUrl(self.options.flash_swf_url), 11 xap_url: o.resolveUrl(self.options.silverlight_xap_url) 12 }); 13 }; 14 15 img.bind("embedded error", function() { 16 $('#' + file.id, self.filelist).removeClass('plupload_file_loading'); 17 this.destroy(); 18 setTimeout(cb, 1); // detach, otherwise ui might hang (in SilverLight for example) 19 }); 20 21 img.load(file.getSource()); 22 }
我修改了我的预览代码,如下
1 var preloader = new mOxie.Image(); 2 preloader.onload = function() { 3 this.embed('pic_'+file.id, { 4 138, 5 height: 147, 6 crop:true, 7 swf_url: o.resolveUrl(up.getOption('flash_swf_url')) 8 9 }); 10 }; 11 preloader.onembedded = function(){ 12 this.destroy(); 13 }; 14 preloader.onerror = function(){ 15 this.destroy(); 16 }; 17 preloader.load(file.getSource());
搞定,然而这种方式不支持gif的预览,有时间再拿出来讨论下
5.qiniu.js中的一些坑
上传的文件公司都是存储在第三方七牛云上,七牛提供了很多sdk,开始准备用后端sdk做一下中转,但效率不太好,然后就换成用qiniu.js(js sdk),我们需要兼容到ie6,然而qiniu.js兼容到ie8+(没有考虑中国国情啊),之前也用过qiniu.js,只修改了源码中的trim,后来七牛自己修改了,在上传图片,附件的时候并没有发现什么异常。这次项目中需要上传视频,我在使用的过程中发现,ie6,7上传视频过程中fileuploaded事件无法触发,可能跟后端给我的token有关,但图片是ok的。去看qiniu.js关于fileuploaded事件封装的源码,
1 var info_extended = {}; 2 plupload.extend(info_extended, that.parseJSON(info), res_downtoken); 3 if (_FileUploaded_Handler) { 4 _FileUploaded_Handler(up, file, JSON.stringify(info_extended)); 5 }
我们知道,在ie6,7并没有JSON对象,而这里在前文中也并没有定义,找到原因了,引入了json2.js,视频上传正常了。最近一直在做附件上传的项目,当页面上有多种附件待上传时,如果包含视频、音频则需要做持久化处理,后台给的token将会不一样,此时如果直接用Qiniu.uploader()函数会导致所有的上传都以最后拿到的token为准。继续去看qiniu.js源码,Qiniu这个变量是QiniuJsSDK的一个实例,我们只需要自己创建实例即可,也就是每次调用时new QiniuJsSDK().
结语
第一次写,若有不对之处,望指正。