资讯专栏INFORMATION COLUMN

如何用鼠标移动一个div(React实现)

Shimmer / 1229人阅读

鼠标事件

要用鼠标移动一个div首先要获取的是鼠标移动的事件。
有三个事件是需要的

onMouseDown 鼠标按下触发

onMouseMove 鼠标移动触发

onMouseUp 鼠标按钮抬起触发

有了这三个事件,就可以获得鼠标完整的按下->移动->抬起完整的操作

移动距离

鼠标onMouseMove事件会得到很多的距离
这些都不是需要的,真正需要的距离是鼠标移动的距离dx和dy
那么我们选取onMouseMove返回的其中的一组clientX和clientY来处理

在class内存储一对变量lastX和lastY

第一次鼠标移动获取数据后将clientX和clientY放入lastX和lastY

第二次鼠标移动获取数据后,当前clientX与lastX的差即是dx,clientY与lastY的差是dy

并且再将clientX和clientY分别放入lastX和lastY,供下次移动使用

将dx和dy加上原来的坐标进行setState操作即可移动div

React实现源码
import React from "react"

export default class extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            translateX: 0,
            translateY: 0,
        };
        this.moving = false;
        this.lastX = null;
        this.lastY = null;
        window.onmouseup = e => this.onMouseUp(e);
        window.onmousemove = e => this.onMouseMove(e);
    }

    onMouseDown(e) {
        e.stopPropagation();
        this.moving = true;
    }

    onMouseUp() {
        this.moving = false;
        this.lastX = null;
        this.lastY = null;
    }

    onMouseMove(e) {
        this.moving && this.onMove(e);
    }

    onMove(e) {
        if(this.lastX && this.lastY) {
            let dx = e.clientX - this.lastX;
            let dy = e.clientY - this.lastY;
            this.setState({ translateX: this.state.translateX + dx, translateY: this.state.translateY + dy })
        }
        this.lastX = e.clientX;
        this.lastY = e.clientY;
    }

    render() {
        return (
            
this.onMouseDown(e)} style={{transform: `translateX(${this.state.translateX}px)translateY(${this.state.translateY}px)`}} >
) } };

onMouseDown事件由div提供,onMouseMove和onMouseUp事件由window提供的原因是防止鼠标移动过快造成事件丢失

this.moving为记录移动开始标志

stopPropagation作用为终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播

div的实际移动由css3属性transform: { translateX, translateY }提供

高阶组件封装的github项目链接react-drag-hoc

更多文章 yjy5264.github.io

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107036.html

相关文章

  • 回到基础:理解 JavaScript DOM

    摘要:事件处理允许对事件做出反应。还可以用代码为多个元素分配相同的事件。指定事件监听器接下来看看怎样为元素分配事件监听器。 翻译:疯狂恶的技术宅https://medium.freecodecamp.o... 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 Javascript DOM(文档对象模型)是一个允许开发人员操纵页面内容、结构和风...

    wemallshop 评论0 收藏0
  • 不会做动画的程序猿不是好的动画师(何用css3动画做动画)

    摘要:一过渡一的作用二的属性二和动画一动画序列书写简例二书写简例常用属性简写属性三完整动画简例代码三转换一转换缩放移动旋转设置元素转换的中心点综合性写法二转换三维坐标系透视呈现位移旋转一过渡一的作用如果你有一个盒子,他的体内也有个小盒子。 ...

    xeblog 评论0 收藏0
  • js鼠标事件解析——何用js实现一个拖动但是不触发其点击事件

    摘要:前言这个是我在做一个的的时候出现的一个问题吧,就是想要他实现拖动的叶子节点,但是的话,不触发他的点击事件。这时候,我就想到一个好方法,就是设计监听其父组件的事件就可以了,反正都会冒泡的。 前言 这个是我在做一个d3的demo的时候出现的一个问题吧,就是想要他实现拖动d3的叶子节点,但是的话,不触发他的点击事件。 在这里,我想过以下两种种方案: 设计监听mousedown,mouseu...

    Tony 评论0 收藏0
  • 何用原生js来写一个swiper滑块插件(上)原理

    嗨~ 这里是芝麻,今天我们一块来做一个滑块插件。那么啥是滑块插件呢?滑块插件能干嘛呢?请看下图: showImg(https://user-gold-cdn.xitu.io/2019/5/27/16af8370362d18e4); 是不是有点印象了,没错,他的最基本的用法就是左右滑动,插件使用者只需要写几行简单的html和js即可实现一个简单滑动效果,不过你完全可以组合各种元素来适应不同的场景...

    Dionysus_go 评论0 收藏0
  • 面试试题总结

    摘要:闲心面试题一任选一题分的区别的区别是无序列表,是有序列表,是定义列表有层次关系。无任何语义,仅仅用作样式化或者脚本化的钩子是有一定语义的,适合有主题性的内容,表示一个专题,一般有标题,但是不可以乱用。诞生于年,由等人创建,后为所收购。 闲心面试题 一、任选一题(5分)a) ul、ol、dl的区别?b) div、section、article的区别? a:ul是无序列表,ol是有序列表,...

    alaege 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<