浏览器图片选择预览、旋转、批量上传的JS代码实现


Posted in Javascript onDecember 04, 2013

工作中遇到的业务场景,和同事一起研究了下,主要是为了兼容IE版本

其实就是一些琐碎的知识点在网上搜集下解决方式,然后集成了下,主要有以下点:

1. IE input type=file的图片预览要用IE的filter css

    progid:DXImageTransform.Microsoft.AlphaImageLoader

   chrome/firefox则用File api的file reader

2. 图片旋转,IE用progid:DXImageTransform.Microsoft.Matrix的filter(filter可以组合用,用空格隔开)

   chrome/firefox用canvas

3. 上传图片,我用的都是不可见的iframe 里的form动态的添加input[type=file]去实现。chrome/firefox可以用xhr,但我懒得去修改了

4. 其中为了实现上传图片不刷新本页面,又能反复选择文件,所以还用一个iframe专门维护一个input[type=file]的列表,比较偷巧。

浏览器图片选择预览、旋转、批量上传的JS代码实现

可以参考下代码,主要是一个主html,然后两个iframe的html,上传的服务端返回的数据为上传成功的file name,用于删除预览图。

// 上传回调
        // resultList -> ['file1', 'file2'] 为上传成功的file name
        var uploadCallback = function(resultList){
            console.log(JSON.stringify(resultList));
            var i = 0;
            for(; i < resultList.length; i++){
                var index = resultList[i].substr('file'.length);
                $(':checkbox[value=' + index + ']').parent().parent().remove();
            }
        };
        $(function(){
            // 保存图片旋转的角度,以便提交给服务端处理
            var rotateAng = {};
            // 用于命名后缀的序号
            var cc = 0;
            // 如果是chrome/ff,需要用file api去生成img
            var genImgTpl = function(input, index){
                return '<img src="/webx/public/1.png" class="main" id="img' + index + '" />';
            };
            var readImgFromInput = function(_input, index){
                var inputDom = _input[0];
                // chrome/ff
                if(inputDom['files']){
                    var reader = new FileReader();
                    reader.onload = function(e){
                        $('img.main:last').attr({src : e.target.result});
                    }
                    reader.readAsDataURL(inputDom['files'][0]);
                }else{
                    var src = _input[0].value;
                    var imgDom = $('#img' + index);
                    imgDom.attr('src-old', src);
                    imgDom.css({
                        float: 'left',
                        position: 'relative',
                        overflow: 'hidden',
                        width: '195px',
                        height: '195px'
                    });
                    imgDom.css({'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='scale',src=\"" + src + "\")"});
                }
            };
            var showImg = function(_input){
                var index = ++cc;
                _input.addClass('hide');
                _input.attr('name', 'file' + index);
                _input.attr('data-index', index);
                var iframeWin = $('#choose')[0].contentWindow;
                iframeWin.addInput(_input);
                var tpl = '<div>' + genImgTpl(_input, index) + 
                    '<span class="choose"><input type="checkbox" value="' + index + '" checked="true" /></span>' + 
                    '<span class="opts turn-right"><img src="img/rightBtn.png" /></span>' + 
                    '</div>';
                $('#imgDiv').append(tpl);
                readImgFromInput(_input, index);
            };
            var addAnother = function(){
                $('#uploadBtn').before('<input type="file" name="file" />');
            };
            // input[type=file]的绑定事件
            $('#uploadDiv input').live('change', function(){
                var path = this.value;
                if(!path){
                    return;
                }
                showImg($(this));
                addAnother();
            });
            // 可以在checkbox时候remove input
//            $('#imgDiv input:checkbox').live('change', function(){
//                var isChecked = $(this).is(':checked');
//                console.log(isChecked);
//            });
            $('#imgDiv span.turn-right').live('click', function(){
                // 上次旋转的角度
                var index = $(this).siblings('span.choose').find('input').val();
                var oldAng = rotateAng[index] || 0;
                var newAng = oldAng + 90;
                rotateAng[index] = newAng;
                $('#img' + index).rotate(90);
            });
            // 表单提交时候根据checkbox,删除未choose的input[type=file]
            $('#uploadBtn').click(function(){
                var choosedNum = $('#imgDiv input:checkbox').filter(':checked').length;
                if(!choosedNum){
                    alert('请选择上传文件!');
                    return false;
                }
                // 选中的序号数组
                var choosedIndexList = $('#imgDiv input:checkbox').filter(':checked').map(function(){
                    return this.value;
                }).get();
                // 两个iframe,一个用于保存选择的input[type=file]
                // 一个用于form upload
                var uploadIframe = $('#upload')[0].contentWindow;
                var chooseIframe = $('#choose')[0].contentWindow;
                var i = 0;
                for(; i < choosedIndexList.length; i++){
                    var index = choosedIndexList[i];
                    var inputFile = chooseIframe.$('#uploadDiv input').filter('[data-index=' + index + ']');
                    uploadIframe.$('#uploadForm').append(inputFile);
                    // 旋转度数
                    var ang = rotateAng[index] || 0;
                    if(ang % 360 != 0){
                        var tplInput = '<input type="hide" name="ang' + index + '" value="' + ang + '" />';
                        uploadIframe.$('#uploadForm').append(tplInput);
                    }
                }
                uploadIframe.doUpload();
                return false;
            });
        });

IE7、8、9和chrome中测试没有问题
Javascript 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(5)
Dec 23 Javascript
img的onload的另类用法
Jan 10 Javascript
JavaScript 未结束的字符串常量常见解决方法
Jan 24 Javascript
JS实现页面超时后自动跳转到登陆页面
Jan 19 Javascript
前端程序员必须知道的高性能Javascript知识
Aug 24 Javascript
JS实现颜色梯度与渐变效果完整实例
Dec 30 Javascript
JavaScript用JSONP跨域请求数据实例详解
Jan 06 Javascript
vue仿element实现分页器效果
Sep 13 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
Mar 29 Javascript
在Koa.js中实现文件上传的接口功能
Oct 08 Javascript
微信小程序indexOf的替换方法(推荐)
Jan 14 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
Jul 21 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
Dec 04 #Javascript
两个数组去重的JS代码
Dec 04 #Javascript
jquery使用jquery.zclip插件复制对象的实例教程
Dec 04 #Javascript
验证控件与Button的OnClientClick事件详细解析
Dec 04 #Javascript
快速解决FusionCharts联动的中文乱码问题
Dec 04 #Javascript
js跑步算法的实现代码
Dec 04 #Javascript
如何在JavaScript中实现私有属性的写类方式(二)
Dec 04 #Javascript
You might like
使用PHP实现密保卡功能实现代码&amp;lt;打包下载直接运行&amp;gt;
2011/10/09 PHP
PHP递归算法的简单实例
2019/02/28 PHP
细品javascript 寻址,闭包,对象模型和相关问题
2009/04/27 Javascript
javascript如何动态加载表格与动态添加表格行
2013/11/27 Javascript
jQuery.holdReady()方法用法实例
2014/12/27 Javascript
jQuery判断对象是否存在的方法
2015/02/05 Javascript
JavaScript 闭包机制详解及实例代码
2016/10/10 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
Angular的$http与$location
2016/12/26 Javascript
JavaScript实现图像模糊化的方法实例
2017/01/15 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
JS原生带缩略图的图片切换效果
2018/10/10 Javascript
laydate时间日历插件使用方法详解
2018/11/14 Javascript
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
vue实现计步器功能
2019/11/01 Javascript
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
[50:27]OG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/30 DOTA
使用Python构建Hopfield网络的教程
2015/04/14 Python
Python遍历pandas数据方法总结
2018/02/09 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
2018/12/06 Python
python3+selenium实现126邮箱登陆并发送邮件功能
2019/01/23 Python
图文详解python安装Scrapy框架步骤
2019/05/20 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
python装饰器三种装饰模式的简单分析
2020/09/04 Python
纯CSS3实现3D旋转书本效果
2016/03/21 HTML / CSS
Everlast官网:拳击、综合格斗和健身相关的体育用品
2020/08/03 全球购物
与UNIX有关的几个名词
2015/09/17 面试题
暑期实习鉴定
2013/12/16 职场文书
门卫岗位职责说明书
2014/08/18 职场文书
审美与表现自我评价
2015/03/09 职场文书
2015年科研工作总结范文
2015/05/13 职场文书
中秋节感想
2015/08/10 职场文书
详解缓存穿透击穿雪崩解决方案
2021/05/28 Redis