浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
innerText和innerHTML 一些问题分析
May 18 Javascript
24款非常有用的 jQuery 插件分享
Apr 06 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
Jan 26 Javascript
JQuery标签页效果的两个实例讲解(4)
Sep 17 Javascript
JS实现网页标题栏显示当前时间和日期的完整代码
Nov 02 Javascript
jQuery弹簧插件编写基础之“又见弹窗”
Dec 11 Javascript
老生常谈 js中this的指向
Jun 30 Javascript
EasyUI加载完Html内容样式渲染完成后显示
Jul 25 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
Aug 15 Javascript
解决vue项目input输入框双向绑定数据不实时生效问题
Aug 05 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设计模式 Delegation(委托模式)
2011/06/26 PHP
PHP对接微信公众平台消息接口开发流程教程
2014/03/25 PHP
详解php反序列化
2020/06/10 PHP
JQuery的Validation插件中Remote验证的中文问题
2010/07/26 Javascript
JS时间选择器 兼容IE6,7,8,9
2012/06/26 Javascript
JQuery+EasyUI轻松实现步骤条效果
2016/02/22 Javascript
JS实现简单易用的手机端浮动窗口显示效果
2016/09/07 Javascript
js随机生成一个验证码
2017/06/01 Javascript
Vue.js移动端左滑删除组件的实现代码
2017/09/08 Javascript
Koa2微信公众号开发之消息管理
2018/05/16 Javascript
JavaScript实现一个带AI的井字棋游戏源码
2018/05/21 Javascript
Vue.js的动态组件模板的实现
2018/11/26 Javascript
javascript实现考勤日历功能
2018/11/29 Javascript
angula中使用iframe点击后不执行变更检测的问题
2020/05/10 Javascript
[03:52]显微镜下的DOTA2第三期——英雄在无聊的时候干什么
2014/06/20 DOTA
[01:44]剑指西雅图 展望TI之CIS战队专访
2014/06/25 DOTA
[01:00:17]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第二场 1月25日
2021/03/11 DOTA
Python中的集合类型知识讲解
2015/08/19 Python
python中lambda()的用法
2017/11/16 Python
python如何让类支持比较运算
2018/03/20 Python
Python将8位的图片转为24位的图片实现方法
2018/10/24 Python
python操作日志的封装方法(两种方法)
2019/05/23 Python
Python pandas实现excel工作表合并功能详解
2019/08/29 Python
pycharm无法导入本地模块的解决方式
2020/02/12 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
详解CSS3伸缩布局盒模型Flex布局
2018/08/20 HTML / CSS
css3实现小箭头各种图形效果
2020/07/08 HTML / CSS
美国领先的精品家居照明和装饰产品在线零售商:LightsOnline.com
2018/01/23 全球购物
财务分析个人的自荐书范文
2013/11/24 职场文书
技术总监岗位职责
2013/12/05 职场文书
座谈会主持词
2014/03/20 职场文书
员工规章制度范本
2015/08/07 职场文书
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript
Python+Selenium实现读取网易邮箱验证码
2022/03/13 Python
mysql 子查询的使用
2022/04/28 MySQL
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers