关于拖拽上传 [一个拖拽上传修改头像的流程]

拖拽是操作系统用户体验最伟大的改进之一。它让人随心所欲的操作,更符合人们的直观感受。

如今现代的浏览器已经有很多支持拖拽文件读取操作,其优点不再复述。前端时间利用拖拽改进了一下网站的头像上传流程,对其中的要点和实践体会做一点总结。

 先看一下总体视图:

1、 文件拖拽接受区域要有明显的标示,并且要尽可能的大(由于版面的原因,这个界面的拖放盒子并不大)。可以用虚线框盒子等样式吸引用户拖拽文件。最好有明显的文字提示和图标配合。

2、 在交互体验上当文件拖入浏览器窗口时,可以用拖放区变换背景颜色等向用户发起放置操作邀请。
实现代码:

 

ExpandedBlockStart.gif 拖拽操作提示
doc.bind({
                
' dragenter ' : function (e){
                    $(
" #brsbox " ).addClass( " dragbrowse " );
                    dropbox.addClass(
" shine " );
                    
return   false ;
                    },
                
' dragleave ' : function (e){
                    dropbox.removeClass(
" shine " );
                    
return   false ;
                    },
                
' drop ' : function (e){
                    stopdft(e);}        
                });
            dropbox.bind({
                
' dragenter ' : function (e){
                    dropbox.addClass(
" candrop " );
                    stopdft(e);},
                
' dragleave ' : function (e){
                    dropbox.removeClass(
" candrop " );
                    stopdft(e);},
                
' dragover ' : function (e){
                    stopdft(e);},
                
' drop ' : function (e){
                    
                    }            

 

 

 对于不支持拖拽的浏览器:

可惜的是 某些浏览器并不支持文件拖拽读取,这其中包括IE9等较现代的浏览器。所以我们必须为不支持拖拽的浏览器准备普通文件浏览上传作为备用方案。
当不支持拖拽文件读取时,界面如下:

 

实现检测的代码如下:

 

ExpandedBlockStart.gif 检测浏览器是否支持拖拽文件读取
it.detectDragable  =   function (){
            filedrag 
=   !! window.FileReader;
            
if ( ! filedrag)  return ;
            $(
" #avtcnt " ).addClass( ' dragable ' );

 

 

 文件放置时的处理:

 

 

 文件放置到可接受区域时,请注意这时候无论你拖放在鼠标上的文件是单个还是多个,在浏览器和操作系统之间传送的e.dataTransefer.files总是复数。也就是多个文件。这也就意味着你需要循环处理鼠标上所携带的文件。
代码如下:

 

ExpandedBlockStart.gif 处理拖拽到浏览器的文件
dropdom.addEventListener( ' drop ' , function (e){
                    it.handlefile(e.dataTransfer.files);
                    stopdft(e);},
false );                
                
            };
            
        it.handlefile 
=   function (files){
            
var  noimg  =   0 ;
            
for ( var  i = 0 ; i < files.length; i ++ ){
                
var  file  =  files[i];
                
if ( ! file.type.match( / image* / )){
                    noimg 
++ ;
                    
if (noimg  == files.length){
                        QSL.optTips(
' 请选择jpg, png, gif 等格式的图片 ' );
                        
return   false ;
                        }
                    
continue ;             
                    }
                
                
var  reader  =   new  FileReader();
                reader.onload 
=   function (e){
                    
var  img  =  document.createElement( ' img ' );
                    img.src 
=  reader.result;
                    setTimeout(
function (){
                        it.imgSize 
=  {
                            w:img.width,
                            h:img.height
                            };
                        },
500 );
                    dropdom.innerHTML
= "" ;
                    img.className 
= ' localimg ' ;
                    it.imgData 
=  reader.result;
                    dropdom.appendChild(img);
                    imagedata.empty().val(reader.result);
                    dropbox.addClass(
" droped " );
                    clearner.show();    
                };
                reader.readAsDataURL(file);
                
                }

 

 

 其中 stopdft(e) 是为了防止浏览器默认操作,不以浏览器打开文件。而转由脚本来处理拖放的文件。

这个流程中,我们需要的是图片文件,所以便利操作 e.dataTransfer.files 对象,查找类型为image的文件。
如果没有,则会提示。

 

读取文件的关键代码: 

var reader = new FileReader();

 

 

reader.onload = function(e){
  var img = document.createElement('img');
    img.src = reader.result;
};
reader.readAsDataURL(file);

本例中我们需要读取图片的高度和宽度属性。所以我们做了如下操作

 setTimeout(function(){

it.imgSize = {
w:img.width,
h:img.height
};
},500);

 虽然是本地文件读取,但是仍然要延时来保证图片确实读取完毕。否则在某些浏览器中会取不到宽高的值。(可否有其他更简便方法?望指出)

删除现有图片,重置拖拽区域:

浏览读取完本地图片之后,要给用户提供删除和重置的选项。(如果是直接上传当然更简便)


ExpandedBlockStart.gif重置拖拽区域
it.resetDropbox  =   function (){
            dropbox.attr(
" class " , " dropbox " )
                .empty()
                .text(
" 将文件拖拽至此区域 " );
            imgData 
=   '' ;
            it.imgData 
=   '' ;
            it.imgSize 
=  {w: 0 ,h: 0 };
            picsub.removeClass(
" uploading " )
            .find(
" button " ).removeAttr( " disabled " )
            .text(
" 上传 " );    
            imagedata.val(
'' );
            clearner.hide();    

 

 

 到这里拖放读取文件的流程基本结束。

利用拖放,读取本地文件的其他优点:

普通的上传更改图片流程是:选择图片-上传图片-上传成功-服务器返回图片-客户端浏览效果

而如果利用拖放读取本地文件则可省去服务器返回 图片的步骤,直接利用reader.result返回的数据。

这样就节省了从服务器读取图片的延迟,并且节省了往返的数据流量。所以只需确认服务器端图片上传成功,图片预览调取本地数据即可:

代码:

ExpandedBlockStart.gif图片上传成功后的处理
function  initImageCrop(url){
    
var  t  =  document.getElementById( " target " ),
        p 
=  document.getElementById( " preview " ),
        b 
=  browseImage,
        s 
=  [],
        ts 
=  [];
    
if (url == ' data ' ){
        t.src 
=  b.imgData;
        p.src 
=  b.imgData;
        posImage(b.imgSize.w,b.imgSize.h);
        }
else {
        
var  cutimg  =   new  Image();
        cutimg.onload 
=   function (){
            t.src 
=  url;
            p.src 
=  url;
            posImage(cutimg.width,cutimg.height);
            }
        cutimg.src 
=  url;    

 

 

 完整DEMO预览(静态文件暂时没有上传成功后的展示(:)

 DEMO脚本

 

 

 

 

转载于:https://www.cnblogs.com/trance/archive/2011/07/13/2105078.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值