浏览器图片选择预览、旋转、批量上传的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 相关文章推荐
FormValidate 表单验证功能代码更新并提供下载
Aug 23 Javascript
面向对象的Javascript之三(封装和信息隐藏)
Jan 27 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
Nov 28 Javascript
JavaScript中的变量作用域介绍
Dec 31 Javascript
浅析JavaScript 箭头函数 generator Date JSON
May 23 Javascript
js获取新浪天气接口的实现代码
Jun 06 Javascript
ionic2 tabs使用 Modal底部tab弹出框
Dec 30 Javascript
vue学习笔记之vue1.0和vue2.0的区别介绍
May 17 Javascript
js学习总结之DOM2兼容处理重复问题的解决方法
Jul 27 Javascript
深入理解vue中slot与slot-scope的具体使用
Jan 26 Javascript
vue实现自定义日期组件功能的实例代码
Nov 06 Javascript
vue.js实现照片放大功能
Jun 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
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
php安装xdebug/php安装pear/phpunit详解步骤(图)
2013/12/22 PHP
php的XML文件解释类应用实例
2014/09/22 PHP
php类的扩展和继承用法实例
2015/06/20 PHP
PHP输入流php://input实例讲解
2015/12/22 PHP
PHP实现一个简单url路由功能实例
2016/11/05 PHP
用js判断用户浏览器是否是XP SP2的IE6
2007/03/08 Javascript
基于jQuery实现点击同时更改两个iframe的网址
2010/07/01 Javascript
json2.js的初步学习与了解
2011/10/06 Javascript
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
JQuery操作tr和td内容的方法实例
2013/03/06 Javascript
解析jquery获取父窗口的元素
2013/06/26 Javascript
javascript判断是否按回车键并解决浏览器之间的差异
2014/05/13 Javascript
jquery实现的蓝色二级导航条效果代码
2015/08/24 Javascript
移动端js图片查看器
2016/11/17 Javascript
JavaScript实现简单评论功能
2017/08/17 Javascript
详解webpack + react + react-router 如何实现懒加载
2017/11/20 Javascript
Echarts之悬浮框中的数据排序问题
2018/11/08 Javascript
详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
2019/04/20 Javascript
[15:20]DOTA2亚洲邀请赛总决赛开幕式表演:羽泉献唱
2017/04/05 DOTA
Django中的用户身份验证示例详解
2019/08/07 Python
利用Python复制文件的9种方法总结
2019/09/02 Python
Pytest如何使用skip跳过执行测试
2020/08/13 Python
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
Vilebrequin美国官方网上商店:法国豪华泳装品牌
2020/02/22 全球购物
自荐信模版
2013/10/24 职场文书
班组长安全生产职责
2013/12/16 职场文书
软件项目开发计划书
2014/05/01 职场文书
农业局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
防灾减灾宣传标语
2014/10/07 职场文书
国防教育标语
2014/10/08 职场文书
公务员个人总结
2015/02/12 职场文书
2015年英语教学工作总结
2015/05/25 职场文书
python 爬取天气网卫星图片
2021/06/07 Python
Win11开始菜单添加休眠选项
2022/04/19 数码科技