react中如何实现pc端原生拖拽?遇到的一些问题

首先我们需要知道拖拽我们需要用到的事件:onmousedown鼠标按下 onmousemove鼠标移动 onmouseup鼠标抬起

其次我们还需要知道我们需要获取哪些值呢?

1、当我们需要拖拽的时候我们首先需要鼠标按下去拖拽,因此我们需要获取到我们鼠标按下时鼠标的x坐标和y坐标。

2、鼠标坐标我们获取到了 但是我们拖拽时还需要获取到盒子的偏移量,因为我们拖动盒子时它的x坐标y坐标都会移动,我们可以通过获取当前点击的xy坐标与鼠标移动时xy坐标做对比,使第一次按下时准备拖拽盒子的xy坐标-我们移动时的xy坐标 +我们盒子偏移量也就是我们当前盒子的offsetLeft/offsetTop来获取到当前距离左侧与距离顶部的距离。

3、我们更改盒子左侧顶部距离,我们需要给盒子设置绝对定位

4、最后鼠标抬起时我们需要让它的鼠标移动为空,是为了我们鼠标抬起时,让盒子固定到当前位置

//js 
const drag = () => {
    //按下鼠标的操作
    console.log(modaldrag.current);
    let box: any = modaldrag.current
    box.onmousedown = function (event: any) {
      //获取鼠标坐标值
      let X1 = event.clientX;
      let Y1 = event.clientY;
      // console.log(X1, Y1, 'X1, Y1');
      //获取盒子偏移位置
      let left = this.offsetLeft
      let top = this.offsetTop
      // console.log(left, top, 'left, top');
      document.onmousemove = function (e) {
        //获取鼠标的坐标值
        let X2 = e.clientX
        let Y2 = e.clientY
        // console.log(X2, Y2);
        let l = X2 - X1 + left
        let t = Y2 - Y1 + top
        // let maxH = document.documentElement.clientHeight - box.clientHeight;
        // let maxW = document.documentElement.clientWidth - box.clientWidth;
        if (l <= 0) {
          l = 0
        }

        // if (l >= maxW - box.clientWidth) {
        //   l = maxW;
        // }
        //修改盒子的位置
        box.style.left = l + 'px'
        box.style.top = t + 'px'

      }
      document.onmouseup = function () {
        document.onmousemove = null
      }

    }
  }
  // 拖拽操作
  const modaldrag: any = useRef()
  useEffect(() => {
    drag()
  }, [])
//html
<div className="model" ref={modaldrag} style={{ backgroundImage: `url(${imgList[inds].img})`, opacity: Model ? "100" : '0' }}>
          <div className="model_header">
            <span>换皮肤</span>
            <span onClick={() => { setModel(false) }}>X</span>
          </div>
          <div className="model_main">
            {
              imgList.map((item, index) => {
                return (
                  <img key={item.id} onClick={clickImg(item, index)} src={item.img} alt="" />
                )
              })
            }
          </div>
        </div>

//less
  .model {
      width: 40vw;
      height: 40vh;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      box-shadow: 1px -2px 10px rgba(0, 0, 0);
      border-radius: 3px;
      background-size: 100% 100%;

      .model_header {
        width: 100%;
        height: 25px;
        line-height: 25px;
        background: #4e9b78;
        display: flex;
        justify-content: space-between;

        span {
          color: #fff;
          font-weight: bold;
          margin: 0px 10px;
          cursor: pointer;
        }
      }
//第二种方法
  const drag = () => {

    let box: any = modaldrag.current
    box.onmousedown = function (event: any) {
      let disX = 0;
      let disY = 0;

      disX = event.pageX - box.offsetLeft;
      disY = event.pageY - box.offsetTop
      event.preventDefault()
      //鼠标移动事件
      document.onmousemove = function (e) {
        //整体可视区也就是页面body的宽高
        const cWidth = document.documentElement.clientWidth || document.body.clientWidth;
        const cHeight = document.documentElement.clientHeight || document.body.clientHeight;

        let lt = e.pageX - disX
        let rt = e.pageY - disY
        console.log(lt, rt);

        if (lt < 0) {
          lt = 0;
        } else if (lt > cWidth - box.offsetWidth) {
          lt = cWidth - box.offsetWidth;
        }
        if (rt < 0) {
          rt = 0
        }
        // else
        //  if(rt>cHeight - box.offsetHeight){
        //      rt = cHeight - box.offsetHeight;
        //  }
        box.style.left = lt + 'px'
        box.style.top = rt + 'px'

      }
      document.onmouseup = function () {
        document.onmousemove = null
      }

    }
  }
  // 拖拽操作
  const modaldrag: any = useRef()
  useEffect(() => {
    drag()
  }, [])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值