浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
新浪中用来显示flash的函数
Apr 02 Javascript
js form 验证函数 当前比较流行的错误提示
Jun 23 Javascript
判断多个input type=file是否有已经选择好文件的代码
May 23 Javascript
javascript中声明函数的方法及调用函数的返回值
Jul 22 Javascript
JS实现控制表格行文本对齐的方法
Mar 30 Javascript
Jquery结合HTML5实现文件上传
Jun 25 Javascript
javascript中利用柯里化函数实现bind方法【推荐】
Apr 29 Javascript
BootStrap按钮标签及基本样式
Nov 23 Javascript
浅谈jQuery before和insertBefore的区别
Dec 04 Javascript
Angular2学习笔记之数据绑定的示例代码
Jan 03 Javascript
jQuery动态操作表单示例【基于table表格】
Dec 06 jQuery
vue使用recorder.js实现录音功能
Nov 22 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中=赋值操作符对不同数据类型的不同行为
2011/01/02 PHP
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
2011/08/02 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
php中的字符编码转换函数用法示例
2014/10/20 PHP
浅析php原型模式
2014/11/25 PHP
laravel 5 实现模板主题功能
2015/03/02 PHP
PHP实现WebService的简单示例和实现步骤
2015/03/27 PHP
javascript function、指针及内置对象
2009/02/19 Javascript
深入解读JavaScript中的Hoisting机制
2015/08/12 Javascript
jQuery实现的分子运动小球碰撞效果
2016/01/27 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
基于slideout.js实现移动端侧边栏滑动特效
2016/11/28 Javascript
React如何利用相对于根目录进行引用组件详解
2017/10/09 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
傻瓜式解读koa中间件处理模块koa-compose的使用
2018/10/30 Javascript
js实现简单的日历显示效果函数示例
2019/11/25 Javascript
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
Python的__builtin__模块中的一些要点知识
2015/05/02 Python
Python使用正则表达式抓取网页图片的方法示例
2017/04/21 Python
Python通过matplotlib画双层饼图及环形图简单示例
2017/12/15 Python
python使用Matplotlib画饼图
2018/09/25 Python
python中selenium库的基本使用详解
2020/07/31 Python
Python如何创建装饰器时保留函数元信息
2020/08/07 Python
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
社区居务公开实施方案
2014/03/27 职场文书
上课随便讲话检讨书
2014/09/12 职场文书
2014年大学生党员评议表自我评价
2014/09/20 职场文书
2014县政府领导班子对照检查材料思想汇报
2014/09/25 职场文书
战略性融资合作协议书范本
2014/10/17 职场文书
2014年社团工作总结范文
2014/11/27 职场文书
2014年妇幼保健工作总结
2014/12/08 职场文书
数据库连接池
2021/04/06 MySQL
如何解决.cuda()加载用时很长的问题
2021/05/24 Python
nginx安装以及配置的详细过程记录
2021/09/15 Servers
前端与RabbitMQ实时消息推送未读消息小红点实现示例
2022/07/23 Java/Android