关于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写的一个DIV 弹出网页对话框
Aug 14 Javascript
Javascript中的isNaN函数使用说明
Nov 10 Javascript
jquery实现商品拖动选择效果代码(自写)
May 28 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
Nov 28 Javascript
简单谈谈javascript中的变量、作用域和内存问题
Aug 30 Javascript
javaScript中定义类或对象的五种方式总结
Dec 04 Javascript
图解Javascript——作用域、作用域链、闭包
Mar 21 Javascript
JavaScript定义及输出螺旋矩阵的方法详解
Dec 01 Javascript
ES6之模版字符串的具体使用
May 17 Javascript
JS函数节流和防抖之间的区分和实现详解
Jan 11 Javascript
JS浮点数运算结果不精确的Bug解决
Aug 01 Javascript
微信小程序开发(二):页面跳转并传参操作示例
Jun 01 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与C#的值类型指向区别的详解
2013/05/21 PHP
PHP 简易输出CSV表格文件的方法详解
2013/06/20 PHP
支持生僻字且自动识别utf-8编码的php汉字转拼音类
2014/06/27 PHP
php实现连接access数据库并转txt写入的方法
2017/02/08 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
基于php解决json_encode中文UNICODE转码问题
2020/11/10 PHP
浅析AngularJS中的生命周期和延迟处理
2015/06/18 Javascript
js原生实现FastClick事件的实例
2016/11/20 Javascript
BootStrap表单验证实例代码
2017/01/13 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
jQuery鼠标悬停内容动画切换效果
2017/04/27 jQuery
JavaScript之RegExp_动力节点Java学院整理
2017/06/29 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
使用vue脚手架(vue-cli)搭建一个项目详解
2019/05/09 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
使用vue-cli4.0快速搭建一个项目的方法步骤
2019/12/04 Javascript
详解JavaScript 事件流
2020/09/02 Javascript
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
2020/10/09 jQuery
js实现碰撞检测
2021/01/29 Javascript
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
Django 前后台的数据传递的方法
2017/08/08 Python
pandas数据分组和聚合操作方法
2018/04/11 Python
python: 判断tuple、list、dict是否为空的方法
2018/10/22 Python
由面试题加深对Django的认识理解
2019/07/19 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
将python安装信息加入注册表的示例
2019/11/20 Python
Python Tkinter Entry和Text的添加与使用详解
2020/03/04 Python
详解HTML5 Canvas绘制时指定颜色与透明度的方法
2016/03/25 HTML / CSS
美国领先的商务贺卡出版商:The Gallery Collection
2018/02/13 全球购物
Everlast官网:拳击、综合格斗和健身相关的体育用品
2020/08/03 全球购物
澳大利亚网上书店:QBD
2021/01/09 全球购物
基层干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
书法社团活动总结
2015/05/07 职场文书
如何使用JavaScript策略模式校验表单
2021/04/29 Javascript
html输入两个数实现加减乘除功能
2021/07/01 HTML / CSS
MySQL 聚合函数排序
2021/07/16 MySQL