实现效果:(可戳 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. ubuntu16.04安装opencv3.4.0

    老实说这篇记录可能拖了有8个月了,早在去年6月份我应该是第一遍安装opencv.当时懒得记录,以为自己什么都能记得住.后来由于电脑各种原因,需要重装opencv,装的时候发现啥都记不住了.然后又得去找 ...

  2. maya cmds pymel selectType() 选择类型切换

    maya cmds pymel selectType() 选择类型切换 import maya.cmds as cmds cmds.selectType( polymeshFace = True ) ...

  3. Android EventBus技能点梳理

    EventBus为Github上的开源项目,地址:https://github.com/greenrobot/EventBus 疑问:1. 现在都是Android Studio创建的项目,如何导入这些 ...

  4. [SCOI2015]小凸玩矩阵

    Description: 给你一个n*m的网格,每个格子有一个数字,每行每列只能选一个数字,问所选数字中第k大的数字的最小值是多少 Hint: \(n \le 250\) Solution: 显然是二 ...

  5. 解决Idea GitLab Clone failed: Authentication failed for的问题

    刚使用GitLab做项目管理,在idea-check versionControl中使用git clone工程,一直报Clone failed: Authentication failed for ‘ ...

  6. mac上配置react-native环境run-ios/run-android命令遇到的问题

    新报错(rn版本:0.53.3)2018.3.6 今天在搞react-native环境时,遇到了一些坑,这里记录一下. 首先最重要的一点是一定要按官网一步一步来,不然可能会出现一些奇奇怪怪的问题! 官 ...

  7. NOIP-螺旋矩阵

    题目描述 一个 n 行 n 列的螺旋矩阵可由如下方法生成: 从矩阵的左上角(第 1 行第 1 列)出发,初始时向右移动:如果前方是未曾经过的格子,则继续前进,否则右转:重复上述操作直至经过矩阵中所有格 ...

  8. 使用Ant Design的select组件时placeholder不生效/不起作用的解决办法

    先来说说使用Ant Design和Element-ui的感觉吧. 公司的项目开发中用的是vue+element-ui,使用了一通下来后,觉得element-ui虽然也有一些问题或坑,但这些小问题或坑凭 ...

  9. 4.再来看看逆向——OD的简介

    目录 1.前言 2.一些设置和配置 3.开始了解OD 代码窗口 数据窗口 小端序问题 前言 前3节主要写了恶意代码用到的手段,接下来先写一下关于逆向调试的一些内容.毕竟逆向比较难理解一点. 一些配置和 ...

  10. js的一些function

    /** * * 根据秒数返回 一个日期范围 * timerFilter(10) */ function timerFilter(n) { let days = 31; // 一月多少天 const o ...