React 实现拖拽功能
实现效果:(可戳 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 实现拖拽功能的更多相关文章
- React Editor 应用编辑器(1) - 拖拽功能剖析
这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...
- RCP:拖拽功能的实现 Drag and Drop
SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...
- js实现登陆页面的拖拽功能
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>登 ...
- duilib中控件拖拽功能的实现方法(附源码)
转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...
- DIV 实现可拖拽 功能(留档)
//可拖拽 功能 $.fn.extend({ //用法:$(element).jqDrag(); //element需要具备定位属性,需要手动调整层叠样式,这里只是修改鼠标拖动效果 ...
- 使用NGUI实现拖拽功能(拼图小游戏)
上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...
- 使用UGUI实现拖拽功能(拼图小游戏)
实现方式 1.引入UGUI自带的事件系统 UnityEngine.EventSystems 2.为我们的类添加接口 IBeginDragHandler, IDragHandler, IEndDragH ...
- JQuery UI的拖拽功能
JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...
- 通过 JS 实现简单的拖拽功能并且可以在特定元素上禁止拖拽
前言 关于讲解 JS 的拖拽功能的文章数不胜数,我确实没有必要大费周章再写一篇重复的文章来吸引眼球.本文的重点是讲解如何在某些特定的元素上禁止拖拽.这是我在编写插件时遇到的问题,其实很多插件的拖拽功能 ...
随机推荐
- eclipse 开发环境问题
1.jdk安装,环境变量设置.主要有两个: JAVA_HOME C:\Program Files\Java\jre7 JRE_HOME C:\Program Files\Java\jre7 2 ...
- 部署Mvc Core SSL网站到Centos并用Nginx作为反向代理
1. 先在本地比如~/Downloads下建立MVC项目 2. 生成mvc使用的ssl证书 2.1. 生成.key文件 openssl genrsa -des3 -out server.key 2 ...
- python re库的正则表达式学习笔记
1. 安装 默认已经安装好了python环境了 re库是python3的核心库,不需要pip install,直接import就行 2. 最简单的模式 字符本身就是最简单的模式 比如:'A', 'I ...
- JMeter通过beanShell脚本生成随机手机号
package xnzx; /** * @author xn088587 * */ public class getTel{ public static int getNum(int start,in ...
- 大数据学习之HDFS基本API操作(下)06
hdfs文件流操作方法一: package it.dawn.HDFSPra; import java.io.BufferedReader; import java.io.FileInputStream ...
- java写word转pdf
https://blog.csdn.net/csdnFlyFun/article/details/79523262
- recyclerview嵌套GridView去屏蔽后者的点击事件,而是前者响应到事件。
无论是标题中的嵌套方式,还是其它列表控件之间的嵌套,都适用. 1.在GirdView的所在布局的根布局中设置改属性: android:descendantFocusability="blac ...
- H5分享功能
web端分享功能 https://www.cnblogs.com/sdcs/p/8328367.html H5分享功能 公司里面做web开发经常会做H5页面,今天整理分享一下. 微信公众号平台 步骤一 ...
- 计蒜客 买书 dfs
题目: https://www.jisuanke.com/course/2291/182236 思路: 递归解决,从第一本书开始,每本书都有两种选择: //index是book里面每本书价格的下标, ...
- SQL语句练习题【主供自己学习、记忆】
1.这是我在面试中遇到的一道sql题,没有答出来,o(╥﹏╥)o 这是我刚才在网上查找函数之后写的SQL语句,能得到这个结果.[谁有不同的方法,欢迎底下评论留言哈] select (DATENAME( ...