# TaskDrag
**Repository Path**: weijing0905/task-drag
## Basic Information
- **Project Name**: TaskDrag
- **Description**: 基于react完成的一个任务拖动小应用
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-11-20
- **Last Updated**: 2022-04-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 一、项目简要说明
使用React框架,采用react-router-dom的路由方式,完成的一个任务拖拽小应用。其中使用的是函数组件,并使用useState、useEffect来对一些状态进行管理。
克隆到本地npm i,然后npm start即可启动
# 二、我的实现步骤
### 1、初始化项目
npx create-react-app name
npm install --save react-router-dom (这里我安装后改成了5.2.0的版本)
启动项目 npm start, 在默认3000端口访问

### 2、配置路由
在App.js文件中
```jsx
{
prepare.map((item, index) => {
return (
{item}
+
)
})
}
```
#### (2)添加任务
点击添加按钮的时候,创建一个input节点,监听输入,失去焦点时判断输入的内容是否为空,为空则取消本次添加,不为空则添加;如果当前没有完成添加无法进行下一次添加。
新添加的任务,所以要更新state
```javascript
let res = [...prepare];
res.push(now);//now是刚刚输入的内容
setPrepare(res);
```
完成修改,并将创建的输入框清除element.remove();
#### (3)任务拖动
使用useEffect钩子
```javascript
useEffect(() => {
let task = document.querySelectorAll("#task");
task.forEach((task) => {
task.addEventListener("mousedown", mouseDown, true);
})
}, [prepare, learning, complete]) //这三个状态发生变化的时候,函数会执行
```
做任务拖动的时候,需要注意,窗口的大小是会改变的,所以我们可以获得三个分类板块在当前窗口的位置,再对任务拖动的时候进行判断是否进入了板块的范围
我需要知道的知识有
- 获得元素在当前窗口的位置
- 相对定位
- top、left设置
- clientX、clientY
- offsetX、offsetY
- 获得 任务盒子的中心 在当前窗口的坐标
- 判断盒子中心坐标 在鼠标抬起的时候是否在三个板块的范围中
- 如果在,进行三个状态的更改,移出的状态要删除元素,移入的地方要新增元素
- 如果不在,则回到最初的位置,设置top、left属性为0
具体代码备注很详细了
#### (4)删除
删除按钮是使用绝对定位来写
```css
.cha{
width: 16px;
height: 16px;
background-color: rgb(165, 65, 65);
display: none;
position: absolute;
top:4px;
left:146px;
border-radius: 50%;
color: white;
text-align: center;
line-height:13px ;
transform: rotate(45deg);
border:none;
cursor: default;
}
```
并且当鼠标停留在对应的任务上时,显示按钮
```css
#task:hover>.cha{
display: block;
}
```
在监听的时候,使用事件代理的方式处理拖动和删除功能
```javascript
const handleDelete = (type, taskName) => {//接收传过来的任务来源——代办、进行中、已完成,以及任务名
if (type === "content_P") {
let newP = [...prepare];
let index = newP.indexOf(taskName);
newP.splice(index, 1);
setPrepare(newP);
}
if (type === "content_L") {
let newL = [...learning];
let index = newL.indexOf(taskName);
newL.splice(index, 1);
setLearning(newL);
}
if (type === "content_C") {
let newC = [...complete];
let index = newC.indexOf(taskName);
newC.splice(index, 1);
setComplete(newC);
}
}
const mouseDown = (event) => {//事件代理
event.stopPropagation();
if (event.target.tagName.toLowerCase() === 'span')
{//如果是点击删除
//...
handleDelete(type,taskName);
} else {
//处理拖动事件
}
}
```