浏览器图片选择预览、旋转、批量上传的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的面向对象方法以及差别
Mar 31 Javascript
js函数中onmousedown和onclick的区别和联系探讨
May 19 Javascript
jQuery Ajax异步处理Json数据详解
Nov 05 Javascript
JS获取随机数函数可自定义最小值最大值
May 08 Javascript
一个可以增加和删除行的table并可编辑表格中内容
Jun 16 Javascript
我的Node.js学习之路(二)NPM模块管理
Jul 06 Javascript
javascript 实现 原路返回
Jan 21 Javascript
js实现仿百度汽车频道选择汽车图片展示实例
May 06 Javascript
移动端JQ插件hammer使用详解
Jul 03 Javascript
整理Javascript函数学习笔记
Dec 01 Javascript
JS返回页面时自动回滚到历史浏览位置
Sep 26 Javascript
为什么说JavaScript预解释是一种毫无节操的机制详析
Nov 18 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 Notice: Undefined index 错误提示解决方法
2010/08/29 PHP
php图像处理函数大全(推荐收藏)
2013/07/11 PHP
PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)
2016/12/02 PHP
PHP如何通过date() 函数格式化显示时间
2020/11/13 PHP
Open and Print a Word Document
2007/06/15 Javascript
jquery的$(document).ready()和onload的加载顺序
2010/05/26 Javascript
jquery键盘事件介绍
2011/01/31 Javascript
js制作的鼠标悬浮时产生的下拉框效果
2012/10/27 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
2015/08/12 Javascript
bootstrap布局中input输入框右侧图标点击功能
2016/05/16 Javascript
jQuery购物车插件jsorder用法(支持后台处理程序直接转换成DataTable处理)
2016/06/08 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
2016/07/20 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
基于Vue.js实现tab滑块效果
2017/07/23 Javascript
基于Vue实例生命周期(全面解析)
2017/08/16 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
Vue不能检测到Object/Array更新的情况的解决
2018/06/26 Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
2018/09/12 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
2020/04/07 Javascript
原生JavaScript实现换肤
2021/02/19 Javascript
Python类属性的延迟计算
2016/10/22 Python
Python数据结构之双向链表的定义与使用方法示例
2018/01/16 Python
python多线程并发及测试框架案例
2019/10/15 Python
python的等深分箱实例
2019/11/22 Python
PyQt5 如何让界面和逻辑分离的方法
2020/03/24 Python
Python 实现敏感目录扫描的示例代码
2020/05/21 Python
Python logging模块异步线程写日志实现过程解析
2020/06/30 Python
药学专业个人的自我评价
2013/12/31 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
亲子活动总结
2014/04/26 职场文书
煤矿安全承诺书
2014/05/22 职场文书
教师政风行风自查自纠报告
2014/10/21 职场文书
《清澈的湖水》教学反思
2016/02/17 职场文书