浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
Jquery下EasyUI组件中的DataGrid结果集清空方法
Jan 06 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
May 01 Javascript
JS实现文字向下滚动完整实例
Feb 06 Javascript
jQuery取消特定的click事件
Feb 29 Javascript
jQuery实现无限往下滚动效果代码
Apr 16 Javascript
利用Angularjs中模块ui-route管理状态的方法
Dec 27 Javascript
JavaScript中递归实现的方法及其区别
Sep 12 Javascript
Node.js使用MySQL连接池的方法实例
Feb 11 Javascript
jquery引入外部CDN 加载失败则引入本地jq库
May 23 jQuery
react项目实践之webpack-dev-serve
Sep 14 Javascript
记录一次完整的react hooks实践
Mar 11 Javascript
如何使用jQuery操作Cookies方法解析
Sep 08 jQuery
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;gt;、self、$this几种操作符的区别介绍
2013/04/24 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
2017/08/01 PHP
JavaScript 设计模式之组合模式解析
2010/04/09 Javascript
基于JQuery的日期联动实现代码
2011/02/24 Javascript
jquery.autocomplete修改实现键盘上下键自动填充示例
2013/11/19 Javascript
JavaScript中的style.cssText使用教程
2014/11/06 Javascript
jQuery 插件开发指南
2014/11/14 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
2015/11/17 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
Bootstrap轮播加上css3动画,炫酷到底!
2015/12/22 Javascript
微信小程序 progress组件详解及实例代码
2016/10/25 Javascript
JS 拦截全局ajax请求实例解析
2016/11/29 Javascript
js图片上传的封装代码
2017/08/01 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
Angular4 Select选择改变事件的方法
2018/10/09 Javascript
layui使用数据表格实现购物车功能
2019/07/26 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
2020/10/24 Javascript
使用Vue实现一个树组件的示例
2020/11/06 Javascript
mac下pycharm设置python版本的图文教程
2018/06/13 Python
[原创]Python入门教程2. 字符串基本操作【运算、格式化输出、常用函数】
2018/10/29 Python
python3 实现对图片进行局部切割的方法
2018/12/05 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
Python 多线程,threading模块,创建子线程的两种方式示例
2019/09/29 Python
python中取绝对值简单方法总结
2020/07/24 Python
Dune London官网:英国著名奢华鞋履品牌
2017/11/30 全球购物
Edwaybuy西班牙:小米在线商店
2019/12/04 全球购物
送给程序员的20个Java集合面试问题
2014/08/06 面试题
工作自我评价分享
2013/12/01 职场文书
汽车销售顾问求职自荐信
2014/01/01 职场文书
应届大学生求职信
2014/07/20 职场文书
甜品店创业计划书
2014/08/14 职场文书
教师批评与自我批评心得体会
2014/10/16 职场文书
2015年食品安全工作总结
2015/05/15 职场文书
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python