浏览器图片选择预览、旋转、批量上传的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控制图片的hover效果(smartRollover.js)
Mar 18 Javascript
jquery实现点击消失的代码
Mar 03 Javascript
JavaScript Serializer序列化时间处理示例
Jul 31 Javascript
Uploadify上传文件方法
Mar 16 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
May 31 Javascript
javascript中获取元素标签中间的内容的实现方法
Oct 08 Javascript
JS 判断某变量是否为某数组中的一个值的3种方法(总结)
Jul 10 Javascript
详解动画插件wow.js的使用方法
Sep 13 Javascript
angularjs的单选框+ng-repeat的实现方法
Sep 12 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
解决layui弹出层layer的area过大被遮挡的问题
Sep 21 Javascript
Java Varargs 可变参数用法详解
Jan 28 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 文件状态缓存带来的问题
2008/12/14 PHP
thinkPHP实现表单自动验证
2014/12/24 PHP
php防止sql注入的方法详解
2017/02/20 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
for 循环性能比较 提高for循环的效率
2009/03/19 Javascript
JavaScript 继承详解(四)
2009/07/13 Javascript
Javascript异步表单提交,图片上传,兼容异步模拟ajax技术
2010/05/10 Javascript
页面只有一个text的时候,回车自动submit的解决方法
2010/08/12 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
2011/06/02 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
JavaScript 基础篇(一)
2012/03/30 Javascript
如何用js控制frame的隐藏或显示的解决办法
2013/03/20 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
javascript表单验证和Window详解
2014/12/11 Javascript
js+css实现上下翻页相册代码分享
2015/08/18 Javascript
js实现简单的碰壁反弹效果
2016/08/30 Javascript
浅析Node.js:DNS模块的使用
2016/11/23 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
Vue 实现列表动态添加和删除的两种方法小结
2018/09/07 Javascript
NVM安装nodejs的方法实用步骤
2019/01/16 NodeJs
vue中过滤器filter的讲解
2019/01/21 Javascript
[46:16]2018DOTA2亚洲邀请赛3月30日 小组赛B组 iG VS VP
2018/03/31 DOTA
详解如何利用Cython为Python代码加速
2018/01/27 Python
使用python PIL库实现简单验证码的去噪方法步骤
2019/05/10 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
2019/06/13 Python
python  文件的基本操作 菜中菜功能的实例代码
2019/07/17 Python
Python ORM编程基础示例
2020/02/02 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
Python matplotlib画图时图例说明(legend)放到图像外侧详解
2020/05/16 Python
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
localStorage的过期时间设置的方法详解
2018/11/26 HTML / CSS
绘画设计学生的个人自我评价
2013/09/20 职场文书
年度评优评先方案
2014/06/03 职场文书
承诺书范本大全
2015/05/04 职场文书
超级礼物观后感
2015/06/15 职场文书
十大必看国产动漫排名,魁拔上线,第二曾在日本播出
2022/03/18 国漫