美文网首页
使用js鼠标(mouse)事件实现拖放html元素

使用js鼠标(mouse)事件实现拖放html元素

作者: mudssky | 来源:发表于2021-08-09 15:42 被阅读0次

    还是一个用react编写的toc组件的例子

    我们把toc组件设置成fix定位,然后改变元素的style的left和top值,就能再页面上随意移动元素了.

    为什么不用drag事件?

    drag事件是html5新添加的api,所以它的兼容性会更差一些.

    另外drag事件也不是很好用, 和我现在想要实现的功能差挺多的,而且复杂度反而更高.

    下面是drag相关的6个事件,

    drag是包含两个物体,从一个元素拖动进入另一个元素,

    针对对象 事件名称 说明
    被拖动的元素 dragstart 在元素开始被拖动时候触发
    drag 在元素被拖动时反复触发
    dragend 在拖动操作完成时触发
    目的地对象 dragenter 当被拖动元素进入目的地元素所占据的屏幕空间时触发
    dragover 当被拖动元素在目的地元素内时触发
    dragleave 当被拖动元素没有放下就离开目的地元素时触发

    而我目前的需求,只会使用到被拖动的元素本身.

    所以并不适合用drag的api.

    使用mouse 鼠标事件实现拖放

    mouse事件相比drag更加底层,能实现更精细的控制.

    下面是这个react组件,拖放事件的代码.

    其中需要注意的是,

    下面这行代码是必要的,因为浏览器自己的拖放处理和我们的拖放处理会产生冲突,我们用return false可以禁止默认行为.

    tocEl.current.ondragstart = function () {
            return false
          }
    
     // 添加拖拽组件位置的监听
      useEffect(() => {
        //   组件生成时,从localStorage获取过去使用的位置
        const jsonstr = localStorage.getItem('tocposition')
        let startPostion = { left: 20, top: 50 }
        if (jsonstr) {
          startPostion = JSON.parse(jsonstr)
        }
        let tocPosition = startPostion
        function moveAt(tocPosition: { left: number; top: number }) {
          tocEl.current!.style.left = tocPosition.left + 'px'
          tocEl.current!.style.top = tocPosition.top + 'px'
        }
        moveAt(tocPosition)
        if (tocEl.current) {
          // console.log(tocEl)
    
          const onMouseDown = function (event: MouseEvent) {
            // 按下鼠标时,我们可以记住鼠标按下的位置相对于拖动地节点左上角的距离
            const shiftX =
              event.clientX - (tocEl.current?.getBoundingClientRect().left || 0)
            const shiftY =
              event.clientY - (tocEl.current?.getBoundingClientRect().top || 0)
    
            // 按下鼠标后,添加移动事件和鼠标放下的事件
            function onMouseMove(event: MouseEvent) {
              // console.log(event.pageX, event.pageY, event.clientX, event.clientY)
              tocPosition = {
                left: event.clientX - shiftX,
                top: event.clientY - shiftY,
              }
              moveAt(tocPosition)
            }
            document.addEventListener('mousemove', onMouseMove)
            function onMouseUp(event: MouseEvent) {
              // 放下后移除事件
              document.removeEventListener('mousemove', onMouseMove)
              document.removeEventListener('mouseup', onMouseUp)
              localStorage.setItem('tocposition', JSON.stringify(tocPosition))
            }
            document.addEventListener('mouseup', onMouseUp)
          }
          tocEl.current.addEventListener('mousedown', onMouseDown)
    
          tocEl.current.ondragstart = function () {
            return false
          }
        }
        return () => {
          //   cleanup
        }
      }, [])
    

    相关文章

      网友评论

          本文标题:使用js鼠标(mouse)事件实现拖放html元素

          本文链接:https://www.haomeiwen.com/subject/tjvzvltx.html