纯js实现浏览器图片选择预览、旋转、批量上传
程序员文章站
2022-06-05 23:16:33
...
工作中遇到的业务场景,和同事一起研究了下,主要是为了兼容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]的列表,比较偷巧
截个图
可以参考下代码,主要是一个主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; }); });
更详细代码请参考附件,希望对需要的童鞋有帮助。
下一篇: 实战PHP/GTK_PHP教程