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


Posted in Javascript onJuly 13, 2011

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

 先看一下总体视图:
关于js拖拽上传 [一个拖拽上传修改头像的流程]
1、 文件拖拽接受区域要有明显的标示,并且要尽可能的大(由于版面的原因,这个界面的拖放盒子并不大)。可以用虚线框盒子等样式吸引用户拖拽文件。最好有明显的文字提示和图标配合。

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

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等较现代的浏览器。所以我们必须为不支持拖拽的浏览器准备普通文件浏览上传作为备用方案。
当不支持拖拽文件读取时,界面如下:

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

实现检测的代码如下:

it.detectDragable = function(){ 
filedrag = !!window.FileReader; 
if(!filedrag) return; 
$("#avtcnt").addClass('dragable');

文件放置时的处理:

 

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

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

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

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

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

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脚本

Javascript 相关文章推荐
JavaScript语句可以不以;结尾的烦恼
Mar 08 Javascript
javascript网页关键字高亮代码
Jul 30 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
Jun 22 Javascript
详解JavaScript编程中的数组结构
Oct 24 Javascript
jquery获取复选框checkbox的值实现方法
May 30 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
Feb 12 Javascript
详解vue.js 开发环境搭建最简单攻略
Jun 12 Javascript
vue-router路由参数刷新消失的问题解决方法
Jun 17 Javascript
快速了解vue-cli 3.0 新特性
Feb 28 Javascript
使用vue打包时vendor文件过大或者是app.js文件很大的问题
Jun 29 Javascript
vue-cli3.0使用及部分配置详解
Aug 29 Javascript
js String.prototype.trim字符去前后空格的扩展
Aug 23 Javascript
使用 JScript 创建 .exe 或 .dll 文件的方法
Jul 13 #Javascript
JS模拟面向对象全解(二、类型与赋值)
Jul 13 #Javascript
JS模拟面向对象全解(一、类型及传递)
Jul 13 #Javascript
一些实用的jQuery代码片段收集
Jul 12 #Javascript
formValidator3.3的ajaxValidator一些异常分析
Jul 12 #Javascript
在IE浏览器中resize事件执行多次的解决方法
Jul 12 #Javascript
JQuery获取当前屏幕的高度宽度的实现代码
Jul 12 #Javascript
You might like
一篇入门的php Class 文章
2007/04/04 PHP
php自定义函数之递归删除文件及目录
2010/08/08 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
php读取目录所有文件信息dir示例
2014/03/18 PHP
php抽象类用法实例分析
2015/07/07 PHP
PHP检测用户是否关闭浏览器的方法
2016/02/14 PHP
JavaScript接口实现代码 (Interfaces In JavaScript)
2010/06/11 Javascript
JS对文本框值的判断示例
2014/03/10 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
基于jquery实现的树形菜单效果代码
2015/09/06 Javascript
JavaScript实现瀑布流布局
2020/06/28 Javascript
JavaScript基于自定义函数判断变量类型的实现方法
2016/11/23 Javascript
微信小程序图表插件(wx-charts)实例代码
2017/01/17 Javascript
用vue和node写的简易购物车实现
2017/04/25 Javascript
vue实现导航标题栏随页面滚动渐隐渐显效果
2020/03/12 Javascript
[06:24]DOTA2 2015国际邀请赛中国区预选赛第二日TOP10
2015/05/27 DOTA
[01:32:10]NAVI vs VG Supermajor 败者组 BO3 第一场 6.5
2018/06/06 DOTA
[05:26]TI10典藏宝瓶套装外观展示
2020/07/03 DOTA
python函数参数*args**kwargs用法实例
2013/12/04 Python
django项目运行因中文而乱码报错的几种情况解决
2017/11/07 Python
基于scrapy的redis安装和配置方法
2018/06/13 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
2019/05/10 Python
python操作日志的封装方法(两种方法)
2019/05/23 Python
Python 实现大整数乘法算法的示例代码
2019/09/17 Python
零基础小白多久能学会python
2020/06/22 Python
英国床垫在线:Mattress Online
2016/12/07 全球购物
全球立体声:World Wide Stereo
2018/09/29 全球购物
积极向上的团队口号
2014/06/06 职场文书
会计毕业生自荐书
2014/06/12 职场文书
2015年党风廉政建设责任书
2015/01/29 职场文书
兵马俑导游词
2015/02/02 职场文书
2015年行政人事部工作总结
2015/05/13 职场文书
运动会主持词大全
2015/07/02 职场文书
运动会广播稿50字
2015/08/19 职场文书
干部理论学习心得体会
2016/01/21 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书