使用 Drag and Drop 给Web应用提升交互体验
什么是 Drag and Drop (拖放)?
简单来说,HTML5 提供了 Drag and Drop API,允许用户用鼠标选中一个可拖动元素,移动鼠标拖放到一个可放置到元素的过程。
我相信每个人都或多或少接触过拖放,比如浏览器多标签页之间的可拖放排序、手机中的App可以随便拖放排序等等,Drag and Drop 已经给我们提供了更便捷、更灵活的网络应用体验。
HTML5 Drag and Drop
DnD 规范定义了基于事件的拖放机制和附加标记,以标记网页上几乎所有 draggable 的元素类型,一个典型的 drag 操作是这样开始的:用户用鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,然后释放鼠标。 在操作期间,会触发一些事件类型,有一些事件类型可能会被多次触发(比如drag 和 dragover 事件类型)。
总结起来很简单:
Drag Source(What to drag) => Drop Target(Where to drop)
拖拽事件
所有的拖拽事件都对应一个 global event handler,Dnd API 一个有8个事件,可以分为绑定在 Drag Source 上3个、绑定在 Drag Target 上5个
Drag Source
| Event | Description |
|---|---|
| dragstart | 当用户开始拖动一个元素或选中的文本时触发。 |
| drag | 当拖动元素或选中的文本时触发。 |
| dragend | 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键)。 |
Drop Target
| Event | Description |
|---|---|
| dragenter | 当拖动元素或选中的文本到一个可释放目标时触发。 |
| dragover | 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次)。 |
| dragexit | 当元素变得不再是拖动操作的选中目标时触发。 |
| dragleave | 当拖动元素或选中的文本离开一个可释放目标时触发。 |
| drop | 当元素或选中的文本在可释放目标上被释放时触发。 |
注意点
- 在鼠标操作拖放期间,有一些事件可能触发多次,(比如:
drag和dragover)。使用时注意防抖或节流 - 在
dragover事件中使用event.preventDefault()阻止默认事件行为时,才能正确触发drop事件 - 在 Firefox 浏览器中触发 drop 时要使用
event.preventDefault()阻止默认事件行为,以防止打开一个新的标签
数据接口
HTML拖拽的数据接口有三个 DataTransfer、DataTransferItem 和 DataTransferItemList。
在进行拖放操作时,DataTransfer 对象用来保存,通过拖放动作,拖动到浏览器的数据。它可以保存一项或多项数据、一种或者多种数据类型。
DataTransfer 常用属性
| 属性 | 类型 | 描述 |
|---|---|---|
| dropEffect | String | 获取 / 设置实际的放置效果,它应该始终设置成 effectAllowed 的可能值之一,copy、move、link、none
|
| effectAllowed | String | 用来指定拖动时被允许的效果。 |
| Files | FileList | 保存一个被存储数据的类型列表作为第一项,顺序与被添加数据的顺序一致。如果没有添加数据将返回一个空列表。 |
| types | DOMStringList | 包含一个在数据传输上所有可用的本地文件列表。如果拖动操作不涉及拖动文件,此属性是一个空列表。 |
DataTransfer 常用方法
void clearData([in String type])String getData(in String type)void setData(in String type, in String data)void setDragImage(in nsIDOMElement image, in long x, in long y)
注意点
- 通过定义
MIME(Multipurpose Internet Mail Exchange)来指定数据传输类型,例如:text/plain
功能检测
想象一下我们想开发一个使用HTML5 DnD API来实现的丰富可交互式的应用。结果因为浏览器不支持,是不是很糟糕。对我们是否需要使用降级方案还是有很重要的参考意义的。
下面有两种常用的方法来帮助我们来检测。
caniuse
Modernizr
Modernizr 是一个出色的可用于检测用户浏览器是否支持 HTML5 和 CSS3 功能的库。
if (Modernizr.draganddrop) {
// Browser supports HTML5 DnD.
} else {
// Fallback to a library solution.
}
实现拖拽
HTML Attribute
实现拖拽元素只需要在dom标签上加入 draggable="true"
<div id="drag-source" draggable="true"></div>
CSS User Interface
user-select
可拖拽元素,建议使用 user-select,避免用户在拖拽时选取到内部元素。
[draggable="true"] {
/*
To prevent user selecting inside the drag source
*/
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
cursor
可拖拽元素,建议使用 cursor,设定可拖拽元素的鼠标游标,提升交互。
[draggable="true"] {
cursor: move;
}
在 Vue 中使用拖拽
Vue 中使用 dnd 可以直接绑定 event 到组件上。
下面栗子包含的内容:
- 使用Vue实现拖放
- 拖放事件以及事件触发的时机
- 拖放事件的一些效果处理
- 拖拽系统文件到浏览器
https://codesandbox.io/embed/...
DnD 能做什么?
- 提升网页上操作交互体验
- 提供列表排序功能
- 本机与浏览器交互
- HTML5游戏
- ...更多
推荐一些不错的DnD库
- interact.js - JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)
- Sortable - Sortable — is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices.
- draggable - The JavaScript Drag & Drop library your grandparents warned you about.
- Vue.Draggable - Vue component allowing drag-and-drop sorting in sync with View-Model. Based on Sortable.js
- vue-grid-layout - A draggable and resizable grid layout, for Vue.js.
- vue-draggable-resizable - Vue2 Component for draggable and resizable elements.
- react-dnd - Drag and Drop for React
- react-beautiful-dnd - Beautiful and accessible drag and drop for lists with React
- react-grid-layout - A draggable and resizable grid layout with responsive breakpoints, for React.
参考
Mozilla HTML_Drag_and_Drop_API
Working with HTML5 Drag-and-Drop
使用 Drag and Drop 给Web应用提升交互体验的更多相关文章
- 通过HTML5的Drag and Drop生成拓扑图片Base64信息
HTML5 原生的 Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过 ...
- 基于HTML5的Drag and Drop生成图片Base64信息
HTML5的Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过Drag ...
- 20 Best Drag and Drop jQuery Plugins--reference
reference from:http://dizyne.net/20-best-drag-drop-jquery-plugins/ jQuery has done a great job repla ...
- 拖放API中的drag和drop实战
原文地址:→传送门 写在前面 在HTML5之前,实现拖放功能需要借助mousedown/mousemove/mouseover/mouseout/mouseup等鼠标事件来完成,HTML5中拖放API ...
- HTML5 之拖放(drag与drop)
拖放(Drag 和 drop)是 HTML5 标准的组成部分. 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. HTML5 拖放实例 ...
- Android 用户界面---拖放(Drag and Drop)(三)
设计拖放操作 本节主要内容如下: 1. 如何开始拖拽: 2. 在拖拽期间如何响应事件: 3. 如何响应落下事件: 4. 如何结束拖放操作. 开始拖拽 用户使用一个拖拽手势开始拖拽,通常是在 ...
- Android 用户界面---拖放(Drag and Drop)(二)
拖拽事件监听器和回调方法 View对象既可以用实现View.OnDragListener接口的拖放事件监听器,也可以用View对象的onDragEvent(DragEvent)回调方法来接收拖拽事 ...
- Android 用户界面---拖放(Drag and Drop)(一)
用Android的拖放框架,能够允许用户使用图形化的拖放手势,把数据从当前布局中的一个View对象中移到另一个View对象中.这个框架包括:拖拽事件类.拖拽监听器.以及辅助的方法和类. 尽管这个框架主 ...
- [Javascript + rxjs] Simple drag and drop with Observables
Armed with the map and concatAll functions, we can create fairly complex interactions in a simple wa ...
随机推荐
- shell中防止意外发生的两个实用的设置
set -o nounset set -o errexit set -o nounset 在默认情况下,遇到不存在的变量,会忽略并继续执行,而这往往不符合预期,加入该选项,可以避免恶果扩大,终止脚本的 ...
- 2019年5月份最热门的JavaScript开源项目
五一假期后工作的第一天,不知道你们调整好状态没有呢? 1-libpku https://github.com/lib-pku/libpku Star 15820 该项目是由一名北大在读大学生整 ...
- oracle——学习之路(SQL基础)
使用create语句创建表 create table 表名 ( 列名 类型 [null | not null], 列名 类型 [null | not null] ) 在 ...
- 20190507-学习dubbo有感于梁飞
“作为一名程序员,BAT肯定是大多数人都想进的,仿佛是一种情愫,就像学生时代的我们对清华北大的向往感觉一样.Dubbo团队中,其中主要负责人就是梁飞了,梁飞的经历还是蛮励志的.梁飞,花名虚极, 200 ...
- PAT B1023 组个最小数(20)
题目描述 给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的 ...
- matplotlib库绘制散点图
假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温随时间(天)变化的某种规律? a = [11,17,16,11,12,11,12,6,6 ...
- hard or 9102 字符串DP---Educational Codeforces Round 57 (Rated for Div. 2)
题意:http://codeforces.com/problemset/problem/1096/D 思路:参考:https://blog.csdn.net/qq_41289920/article/d ...
- 并不对劲的复健训练-CF1205B Shortest Cycle
题目大意 有\(n\)(\(n\leq 10^5\))个数\(a_1,...,a_n\)(\(a\leq 10^{18}\)).有一个图用这个方法生成:若\(a_i\)按位与\(a_j\)不为0,则在 ...
- MyBatis 体系结构、根配置文件、Mapper映射文件
一.MyBatis的体系结构 1.SqlSessionFactory对象 SqlSessionFactory对象是MyBatis的管理核心,它是单个数据库映射关系经过编译后的内存镜像,是创建SqlSe ...
- js 动态添加Table tr,选中与不选中checkbox行数NO的变化
首次加载进入页面,如图: 注:Table是在js中拼接字符串循环动态添加的(拼接字符串,详见之前随笔) 点击Line2 checkbox后,效果如图: 实现的效果就是: 点击checkbox — 显示 ...