浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
msn上的tab功能Firefox对childNodes处理的一个BUG
Jan 21 Javascript
Jquery 表单验证类介绍与实例
Jun 09 Javascript
js抽奖实现随机抽奖代码效果
Dec 02 Javascript
js实现模拟银行卡账号输入显示效果
Nov 18 Javascript
JS获取CSS样式(style/getComputedStyle/currentStyle)
Jan 19 Javascript
探索Javascript中this的奥秘
Dec 11 Javascript
angular仿支付宝密码框输入效果
Mar 25 Javascript
分享十三个最佳JavaScript数据网格库
Apr 07 Javascript
JavaScript通过改变文字透明度实现的文字闪烁效果实例
Apr 27 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
Dec 05 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
Dec 06 Javascript
vue-test-utils初使用详解
May 23 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比较两个绝对时间的大小
2014/01/31 PHP
解密ThinkPHP3.1.2版本之独立分组功能应用
2014/06/19 PHP
php程序内部post数据的方法
2015/03/31 PHP
微信公众号OAuth2.0网页授权问题浅析
2017/01/21 PHP
详细解读php的命名空间(二)
2018/02/21 PHP
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
2011/11/30 Javascript
用javascript添加控件自定义属性解析
2013/11/25 Javascript
jQuery实现固定在网页顶部的菜单效果代码
2015/09/02 Javascript
详解JavaScript UTC时间转换方法
2016/01/07 Javascript
JS数组返回去重后数据的方法解析
2017/01/03 Javascript
Vue.js学习之计算属性
2017/01/22 Javascript
Webpack如何引入bootstrap的方法
2017/06/17 Javascript
浅谈vue路径优化之resolve
2017/10/13 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
jQuery轮播图功能制作方法详解
2019/12/03 jQuery
Vue-resource安装过程及使用方法解析
2020/07/21 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
浅谈django model的get和filter方法的区别(必看篇)
2017/05/23 Python
使用python爬虫实现网络股票信息爬取的demo
2018/01/05 Python
Python装饰器简单用法实例小结
2018/12/03 Python
详解Appium+Python之生成html测试报告
2019/01/04 Python
Python 中如何实现参数化测试的方法示例
2019/12/10 Python
python 调整图片亮度的示例
2020/12/03 Python
HTML5 placeholder(空白提示)属性介绍
2013/08/07 HTML / CSS
秘书岗位职责
2013/11/18 职场文书
门卫管理制度范本
2015/08/05 职场文书
和领导吃饭祝酒词
2015/08/11 职场文书
三好学生评选事迹材料(2016精选版)
2016/02/25 职场文书
python3+PyQt5+Qt Designer实现界面可视化
2021/06/10 Python
Java中try catch处理异常示例
2021/12/06 Java/Android
mysql查询结果实现多列拼接查询
2022/04/03 MySQL
Mysql数据库group by原理详解
2022/07/07 MySQL
Python实现聚类K-means算法详解
2022/07/15 Python