实现效果:(可戳 https://codepen.io/wenr/pen/EGEQxp 查看)

因为工作中会用到 JIRA 所以想实现一下相似的功能,顺便学习一下 H5 的拖拽。不支持拖拽改变顺序,感觉有点麻烦,而且没必要。感觉相关的博文好少的,大部分都是直接上代码,没有解释。

图片默认可以拖动,其他元素的拖动效果同图片。正常的 div 是不能被拖动的,鼠标点击选择后移动没有效果,需要加  draggable="true" 使得元素可以被拖动。

拖拽相关的几个事件,有被拖动元素的事件,也有拖动进入的容器元素的事件。

被拖拽元素的事件:ondragstart,ondragend

放置元素的事件:ondragenter、ondragover、ondragleave、ondrop

顾名思义,不需要解释。

需要注意是  ondragover 的默认事件 Reset the current drag operation to "none". 所以想让一个元素可放置,需要重写 ondragover

element.ondragover = event => {
event.preventDefault();
// ...
}

当一个元素是可放置的,拖拽经过时鼠标会变成加号(cursor: copy;)

有一个对象  dataTransfer 可以用来存储拖拽数据。

dragEle.ondragstart = e => e.dataTransfer.setData('item', e.target.id);

拖拽开始时触发,把被拖拽元素的 id 存入  e.dataTransfer

然后在 ondrop 的时候 可以获取到这个值 (ondragenter、ondragover、ondragleave 获取不到...)

putEle.ondrop = function(e) {
let id = e.dataTransfer.getData('item');
// ...
}

简单的应用:

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.wrapper {display: flex;border: 1px solid orangered;padding: 10px;}
.col {border: 1px solid #808080;height: 500px;width: 200px;margin: 0 10px;padding: 10px;}
.item {border: 1px solid #808080;margin: 5px 0;}
</style>
</head>
<body>
<div class="wrapper">
<div class="col1 col">
<div class="item" id="item1" draggable="true">item1</div>
<div class="item" id="item2" draggable="true">item2</div>
<div class="item" id="item3" draggable="true">item3</div>
</div>
<div class="col2 col"></div>
<div class="col3 col"></div>
<div class="col4 col"></div>
</div>
<script>
let cols = document.getElementsByClassName('col');
for (let col of cols) {
col.ondragenter = e => {
console.log('放置元素 ondragenter', '<' + e.dataTransfer.getData('item') + '>');
}
col.ondragover = e => {
e.preventDefault();
console.log('放置元素 ondragover', '<' + e.dataTransfer.getData('item') + '>');
}
col.ondragleave = e => {
console.log('放置元素 ondragleave', '<' + e.dataTransfer.getData('item') + '>');
}
col.ondrop = function(e) {
console.log('放置元素 ondrop', '<' + e.dataTransfer.getData('item') + '>');
this.append(document.getElementById(e.dataTransfer.getData('item')));
}
}
let items = document.getElementsByClassName('item');
for (let item of items) {
item.ondragstart = e => {
console.log('拖拽元素 ondragstart');
e.dataTransfer.setData('item', e.target.id);
}
item.ondragend = e => {
console.log('拖拽元素 ondragend');
}
}
</script>
</body>
</html>

文章开头部分的 React 写的 demo

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<style>
.item {
border: 1px solid #1da921;
width: 180px;
border-radius: 5px;
box-shadow: 0 0 5px 0 #b3b3b3;
margin: 5px auto;
background: #fff;
}
.item.active {
border-style: dashed;
}
.item-header {
font-size: 12px;
color: #9e9e9e;
padding: 3px 5px;
}
.item-main {
padding: 5px;
font-size: 14px;
color: #424242;
height: 36px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.item-header-point {
background: #ccc;
float: right;
padding: 0 4px;
min-width: 10px;
text-align: center;
color: #fff;
border-radius: 50%;
}
.col {
border: 1px solid #d2d2d2;
flex-grow: 1;
width: 180px;
height: 100%;
margin: 0 2px;
background: #eee;
flex-grow: 1;
display: flex;
flex-direction: column;
}
.col-header {
height: 40px;
line-height: 40px;
background: #1DA921;
color: #fff;
text-align: center;
}
.col-main {
overflow: auto;
flex-grow: 1;
}
.col-main.active {
background: #00ad23;
opacity: 0.1;
}
.task-wrapper {
display: flex;
height: 400px;
width: 700px;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const STATUS_TODO = 'STATUS_TODO';
const STATUS_DOING = 'STATUS_DOING';
const STATUS_DONE = 'STATUS_DONE'; const STATUS_CODE = {
STATUS_TODO: '待处理',
STATUS_DOING: '进行中',
STATUS_DONE: '已完成'
}
let tasks = [{
id: 0,
status: STATUS_TODO,
title: '每周七天阅读五次,每次阅读完要做100字的读书笔记',
username: '小夏',
point: 10
}, {
id: 1,
status: STATUS_TODO,
title: '每周七天健身4次,每次健身时间需要大于20分钟',
username: '橘子

React 实现拖拽功能的更多相关文章

  1. React Editor 应用编辑器(1) - 拖拽功能剖析

    这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...

  2. RCP:拖拽功能的实现 Drag and Drop

    SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...

  3. js实现登陆页面的拖拽功能

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>登 ...

  4. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  5. DIV 实现可拖拽 功能(留档)

    //可拖拽 功能 $.fn.extend({    //用法:$(element).jqDrag();    //element需要具备定位属性,需要手动调整层叠样式,这里只是修改鼠标拖动效果    ...

  6. 使用NGUI实现拖拽功能(拼图小游戏)

    上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...

  7. 使用UGUI实现拖拽功能(拼图小游戏)

    实现方式 1.引入UGUI自带的事件系统 UnityEngine.EventSystems 2.为我们的类添加接口 IBeginDragHandler, IDragHandler, IEndDragH ...

  8. JQuery UI的拖拽功能

    JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...

  9. 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽

    前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...

随机推荐

  1. MyCat读写分离-笔记(四)

    概述 Mycat能够实现数据库读写分离,不能实现主从同步,数据库的备份还是基于数据库层面的.Mycat只是数据库的中间件: Mycat读写分离配置 在MySQL中间件出现之前,对于MySQL主从集群, ...

  2. sql查询单表之中大于2条的数据

    SELECT COUNT(字段)AS COUNT,字段FROM 表名 GROUP BY 字段 HAVING COUNT >=

  3. java 基本数据类型的取值

    一. 1.基本类型:short 二进制位数:16 包装类:java.lang.Short 最小值:Short.MIN_VALUE=-32768 (-2的15此方)最大值:Short.MAX_VALUE ...

  4. macof python攻击脚本

    #!/usr/bin/python import sys from scapy.all import * import time iface="eth0" if len(sys.a ...

  5. AI零基础入门之人工智能开启新时代—上篇

    人工智能的发展史及应用 开篇:人工智能无处不在 人工智能的发展历程 · 1945艾伦图灵在论文<计算机器不智能>中提出了著名的图灵测试,给人工智能的収展产生了深远的影响. · 1951年, ...

  6. Java equals()方法和hashCode()方法

    equals()方法 如果满足了以下任何一个条件,就不需要覆盖equals()方法: 1 类的每个实例本质上都是唯一的. 2 不关心类是否提供了“逻辑相等”的测试功能. 3 父类已经覆盖了equals ...

  7. 再回首数据结构—数组(Golang实现)

    数组为线性数据结构,通常编程语言都有自带了数组数据类型结构,数组存放的是有个相同数据类型的数据集: 为什么称数组为线性数据结构:因为数组在内存中是连续存储的数据结构,数组中每个元素最多只有左右两个方向 ...

  8. MVC5 Razor视图中不规范书写导致的编译问题

    今天碰到一个非常让人难以理解的问题,如图所示,但是我在代码中并没有找到缺失"}"的地方: 根据源文件提示有去 AppData\Local\Temp\Temporary ASP.NE ...

  9. java.lang.ClassCastException: net.sf.json.JSONNull cannot be cast to net.sf.json.JSONObject的解决方法

    报错情况已经说明了,在百度查了好几个解决方法,这里总结一下: 首先:加一个判断是否为空,再做操作 // 得到json串 String jsonString = UtilPOSTGET.UPost(FO ...

  10. linux android开发环境搭建

    android开发环境搭建的一些有用链接:1.sdk manager的国内服务器http://www.cnblogs.com/huangjacky/p/4077982.html2.常见问题的解决htt ...