关于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 相关文章推荐
IE7提供XMLHttpRequest对象为兼容
Mar 08 Javascript
javascript实现unicode和字符的互相转换
Jul 18 Javascript
分析 JavaScript 中令人困惑的变量赋值
Aug 13 Javascript
DWR实现模拟Google搜索效果实现原理及代码
Jan 30 Javascript
JS操作数据库的实例代码
Oct 17 Javascript
JS+CSS实现Li列表隔行换色效果的方法
Feb 16 Javascript
Vuejs2 + Webpack框架里,模拟下载的实例讲解
Sep 05 Javascript
详解Vue中watch的详细用法
Nov 28 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
Dec 20 Javascript
关于AOP在JS中的实现与应用详解
May 06 Javascript
vue使用高德地图根据坐标定位点的实现代码
Aug 22 Javascript
游戏开发中如何使用CocosCreator进行音效处理
Apr 14 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面向对象分析设计的61条军规小结
2010/07/17 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
再推荐十款免费的php开发工具
2015/11/09 PHP
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
2016/09/11 PHP
jQuery EasyUI中对表格进行编辑的实现代码
2010/06/10 Javascript
优化innerHTML操作(提高代码执行效率)
2011/08/20 Javascript
使用javascript实现ListBox左右全选,单选,多选,全请
2013/11/07 Javascript
JS实现的生成随机数的4个函数分享
2015/02/11 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
jQuery多级联动下拉插件chained用法示例
2016/08/20 Javascript
详解jQuery uploadify文件上传插件的使用方法
2016/12/16 Javascript
javaScript动态添加Li元素的实例
2018/02/24 Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
2020/08/19 Javascript
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
[02:20]DOTA2亚洲邀请赛 IG战队出场宣传片
2015/02/07 DOTA
[34:08]2018DOTA2亚洲邀请赛3月29日 小组赛B组 VP VS EG
2018/03/30 DOTA
Python调用微信公众平台接口操作示例
2017/07/08 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
Flask框架通过Flask_login实现用户登录功能示例
2018/07/17 Python
python实现合并两个排序的链表
2019/03/03 Python
详解python播放音频的三种方法
2019/09/23 Python
Python中__repr__和__str__区别详解
2019/11/07 Python
Python telnet登陆功能实现代码
2020/04/16 Python
用python进行视频剪辑
2020/11/02 Python
详解Python中@staticmethod和@classmethod区别及使用示例代码
2020/12/14 Python
美国最佳在线航班预订网站:LookupFare
2019/03/26 全球购物
WatchShop法国:英国排名第一的独立手表零售商
2020/02/17 全球购物
自我鉴定范文
2013/11/10 职场文书
前台接待员岗位职责
2014/01/02 职场文书
《乡愁》教学反思
2014/02/18 职场文书
2015年元旦活动总结
2014/05/09 职场文书
小学生成绩单评语
2014/12/31 职场文书
上市公司财务总监岗位职责
2015/04/03 职场文书
地道战观后感2000字
2015/06/04 职场文书