浏览器图片选择预览、旋转、批量上传的JS代码实现

  工作中遇到的业务场景,和同事一起研究了下,主要是为了兼容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中测试没有问题