本文来自网易云社区

作者:刘凌阳

前言

本文依据半年前本人的分享《浅谈js拖拽》撰写,算是一篇迟到的文章。

基本思路

虽然现在关于拖拽的组件库到处都是,HTML5也把拖放纳入了标准。但考虑到兼容问题,我们还是从最古老的方式开始讲起。

onmousedown:模拟开始拖拽事件。   鼠标按键按下即发生  onmousedown  事件。  获取鼠标位置,获取被拖拽元素的位置,记录两者之间的纵横坐标的差值。对  document  元素绑定  onmousemove,onmouseup  事件。

为什么是对  document  绑定而不是对被拖动的元素绑定呢?原来是如果对被拖动元素绑定的话当鼠标拖动过快时,会导致鼠标与被拖动元素的脱离。

onmousemove:模拟拖拽中事件。  鼠标拖动即发生  onmousemove  事件。  将被拖拽元素的  position  改成绝对位置,这个可以通过  left  和  top  改变该元素的位置,从而使得该元素随着鼠标的拖拽而移动。获取鼠标位置,将鼠标  x  坐标(  e.clientX  )减去第  2  步储存的横坐标差作为被拖动元素的  left  值,将鼠标y  坐标(  e.clientY  )减去第  2  步储存的纵坐标差作为被拖动元素的  top  值。实现元素跟随鼠标拖动的效果。

onmouseup:模拟拖拽结束事件。  鼠标按键弹起即发生  onmouseup  事件。可以回收  onmousemove  和  onmousedown中的  事件和变量,一次拖拽至此结束。

(  nej  也提供了拖拽的一个简单案例,位于  util/dragger/  下,代码就不贴出来了,有兴趣的童鞋可以自行查阅,毕竟看文字实在是过于枯燥了。  )

HTML5拖放

有古老的方式自然有潮流的方式,如果你无需考虑兼容性问题的话,笔者强烈建议你使用HTML5提供的拖放API   。如果你还未曾了解,提供你一个  简单的HTML5拖放实例  http://www.w3school.com.cn/tiy/t.asp?f=html5_draganddrop

让我们一起来看看HTML5拖放相关的一些知识点。

7个事件:

dragstart  :当用户开始拖动对象时触发。

dragenter  :    当鼠标第一次经过目标元素,且有拖动发生时触发。此事件的监听者应指明在这个位置上是否允许  drop  ,或者监听者不执行任何操作,那么  drop  默认是不允许的。

dragover  :当鼠标经过一个元素时,且有拖动发生时触发    。

dragleave  :当鼠标离开一个元素,且有拖动在发生时触发。

drag  :    当对象被拖动,每次移动鼠标时触发。

drop  :在  drag  操作的最后发生  drop  时,在元素上触发此事件。监听者应该负责检索拖动的数据,并插入  drop  的位置。

dragend  :    在拖动对象时放开鼠标按键时触发。

draggable属性:

如果网页元素的draggable元素为true,这个元素就是可以拖动的。

<div draggable="true">Draggable Div</div>

dataTransfer对象:

拖动过程中,回调函数接受的事件参数,有一个dataTransfer属性。它指向一个对象,包含了与拖动相关的各种信息。

dataTransfer对象的属性:

  • dropEffect:拖放的操作类型,决定了浏览器如何显示鼠标形状,可能的值为copy、move、link和none。

  • effectAllowed:指定所允许的操作,可能的值为copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默认值,等同于all,即允许一切操作)。

  • files:包含一个FileList对象,表示拖放所涉及的文件,主要用于处理从文件系统拖入浏览器的文件。

  • types:储存在DataTransfer对象的数据的类型。

  • dataTransfer对象的方法:

  • setData(format, data):在dataTransfer对象上储存数据。第一个参数format用来指定储存的数据类型,比如text、url、text/html等。

  • getData(format):从dataTransfer对象取出数据。

  • clearData(format):清除dataTransfer对象所储存的数据。如果指定了format参数,则只清除该格式的数据,否则清除所有数据。

  • setDragImage(imgElement, x, y):指定拖动过程中显示的图像。默认情况下,许多浏览器显示一个被拖动元素的半透明版本。参数imgElement必须是一个图像元素,而不是指向图像的路径,参数x和y表示图像相对于鼠标的位置。

dataTransfer对象,   允许在其上存储数据,这使得在被拖动元素与目标元素之间传送信息成为可能。

e.preventDefault():

ondragover有一个默认行为,那就是当  ondragover触发时,ondrop会失效!

如何阻止?

ondragover = function(e){e.preventDefault();    ....}

附一张整理好的图片供大家理解:

案例

扯了这么多,最后再举个栗子来结束本文。先上图片...

这是笔者在网易有数项目中的一个需求,实现文件拖拽上传。

实现步骤:

1.监听事件

其中dragenter和dragleave只是处理了外框高亮的效果,如上面图片所示。

需要注意的是一定要将dragover的默认事件取消掉,不然无法触发drop事件。可以用preventDefault(),也可以用nej的_v._$stop(_event)。如需拖拽页面里的元素,需要给其添加属性draggable=”true”。这些上文已经有所提及。

2.处理drop事件

在drop事件回调函数中通过_event.dataTransfer.files获取拖拽文件列表。dataTransfer对象真是个好东西。

3.发送文件数据

使用FormData模拟表单数据AJAX提交文件流。

至此,HTML5的文件拖拽上传就实现了,是不是很easy?

网易云大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者刘凌阳授权发布

相关文章:
【推荐】 Innodb实践总结(一)
【推荐】 网易易盾验证码的安全策略
【推荐】 nova状态同步

浅谈js拖拽的更多相关文章

  1. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  2. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  3. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  4. js拖拽效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  6. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  7. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  8. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  9. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

随机推荐

  1. mac上Android环境变量配置

    1.AndroidSDK路径查看 (1)AndroidStudio: 菜单栏AndroidStudio > Preferences > Appearences&Behavior & ...

  2. 洗礼灵魂,修炼python(62)--爬虫篇—模仿游戏

    前言 <模仿游戏>这个电影相信如果你是搞IT的,即使没看过也听过吧?电影讲述了计算机之父——阿兰-图灵的一些在当时来讲算是计算机史里的里程碑事迹了.而[模仿游戏]这个名字咋一看,貌似和电影 ...

  3. C#语言————选择结构

    int[] num = new int[] {23,76,54,87,51,12 }; //冒泡排序 for (int i = 0; i < num.Length - 1; i++) { for ...

  4. rsync续传大目录一例

    场景 要将大约60T的文件从一台服务器上搬到另外一台上.两边分区还不一样大,一边是一个整的60T大分区,另一边是15T一个的小分区. 解决思路 类比茶壶倒水,一个分区一个分区的填,填满一个再填第二个. ...

  5. Oracle 表操作(转)

    1.增加新字段:alter table table_name add (name varchar(20) default 'http://www.zangjing.net/');. 2.修改表字段:a ...

  6. redis数据库的简单介绍

    NoSQL:一类新出现的数据库(not only sql) 泛指非关系型的数据库 不支持SQL语法 存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是KV形式 NoSQL的世 ...

  7. linux 下正则匹配时间命名格式的文件夹

    用正则表达式匹配时间格式命名的文件夹 ls mypath | grep -E "[0-9]{4}-[0-9]{1,2}" mypath为需要查询的目录 查询出来的文件夹格式为:例 ...

  8. January 08th, 2018 Week 02nd Monday

    To be yourself in a world that is constantly trying to make you something else is the greatest accom ...

  9. 使用golang的slice来模拟栈

    slice(切片):底层数据结构是数组 stack(栈):一种先进后出的数据结构 普通版的模拟写入和读取的栈 package main import "fmt" //栈的特点是先进 ...

  10. activiti获取可回退的节点

    在处理流程回退时,需要获取某个节点当前可以回退到的节点,简单分析下: 1. 只支持回退到userTask. 2. 如果流程流转过某节点时生成了多个任务,从其中某一个任务回退到该节点后,不处理另外的任务 ...