浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
Js中获取frames中的元素示例代码
Jul 30 Javascript
javascript 拷贝节点cloneNode()使用介绍
Apr 03 Javascript
js处理表格对table进行修饰
May 26 Javascript
js实现简单的验证码
Dec 25 Javascript
javascript正则表达式之分组概念与用法实例
Jun 16 Javascript
最全面的百度地图JavaScript离线版开发
Sep 10 Javascript
jQuery插件ajaxFileUpload使用详解
Jan 10 Javascript
Jquery鼠标放上去显示全名的实现方法
Feb 06 Javascript
简单谈谈关于Angular Cli打包的事
Sep 05 Javascript
详解如何去除vue项目中的#——History模式
Oct 13 Javascript
详解React-Router中Url参数改变页面不刷新的解决办法
May 08 Javascript
小程序转发探索示例
Feb 19 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
动漫定律:眯眯眼都是怪物!这些角色狠话不多~
2020/03/03 日漫
php垃圾代码优化操作代码
2010/08/05 PHP
PHP导航下拉菜单的实现如此简单
2013/09/22 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
2011/07/08 Javascript
基于jquery实现select选择框内容左右移动添加删除代码分享
2015/08/25 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
Angular的MVC和作用域
2016/12/26 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
2018/05/08 Javascript
JS中验证整数和小数的正则表达式
2018/10/08 Javascript
Vue记住滚动条和实现下拉加载的完美方法
2020/07/31 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
pytorch构建网络模型的4种方法
2018/04/13 Python
Python3.5 Json与pickle实现数据序列化与反序列化操作示例
2019/04/29 Python
Python GUI自动化实现绕过验证码登录
2020/01/10 Python
Python中实现输入超时及如何通过变量获取变量名
2020/01/18 Python
jupyter notebook 使用过程中python莫名崩溃的原因及解决方式
2020/04/10 Python
python使用QQ邮箱实现自动发送邮件
2020/06/22 Python
如何基于Django实现上下文章跳转
2020/09/16 Python
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
巴西女装购物网站:Eclectic
2018/04/24 全球购物
英国最大的运动营养公司之一:LA Muscle
2018/07/02 全球购物
优秀毕业生自我鉴定
2014/01/19 职场文书
标准自荐信范文
2014/01/29 职场文书
开学典礼主持词
2014/03/19 职场文书
竞聘演讲稿
2014/04/24 职场文书
道路运输企业安全生产责任书
2014/07/28 职场文书
介绍信如何写
2015/01/31 职场文书
区域经理岗位职责
2015/02/02 职场文书
高中运动会前导词
2015/07/20 职场文书
离婚协议书范本(2016最新版)
2016/03/18 职场文书
七年级作文之英语老师
2019/10/28 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python