笑丶日葵 2023-05-15 09:25 采纳率: 41.9%
浏览 25
已结题

如何优化drag事件

使用vue-grid-layout实现从侧边栏拖拽组件到设计器中,drag事件会再过程中执行多次造成卡顿,当松开鼠标后还会等待drag事件执行结束才会显示组件(用dragend控制显示),现在怎么优化这个drag事件,使用节流行不通,delay 设置多少都一样

<div
                class="box"
                v-for="(item, index) in items.list"
                :key="index"
                @drag="dragThrottle(item)"
                @dragend="dragend(item)"
                draggable="true"
                unselectable="on"
              >

 throttle(fn, delay = 100) {
      let timer = null
      return function () {
        if (!timer) {
          timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
          }, delay)
        }
      }
    },
    dragThrottle(item) {
      this.throttle(this.drag(item), 1000)
    },

    drag(item) {
      console.log('drag')
      const parentRect = document.getElementById('custom-design').getBoundingClientRect()
      const mouseInGrid =
        mouseXY.x > parentRect.left &&
        mouseXY.x < parentRect.right &&
        mouseXY.y > parentRect.top &&
        mouseXY.y < parentRect.bottom
      if (mouseInGrid && this.layout.findIndex((item) => item.i === 'drop') === -1) {
        this.layout.push({
          x: (this.layout.length * 2) % (this.colNum || 12),
          y: this.layout.length + (this.colNum || 12),
          w: item.w,
          h: item.h,
          i: 'drop',
        })
      }
      const index = this.layout.findIndex((item) => item.i === 'drop')
      const indexId = Date.now()
      if (index !== -1) {
        try {
          this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = 'none'
        } catch {}
        const el = this.$refs.gridlayout.$children[index]
        el.dragging = { top: mouseXY.y - parentRect.top, left: mouseXY.x - parentRect.left }
        const new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left)
        if (mouseInGrid) {
          this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, item.h, item.w)
          DragPos.i = indexId
          DragPos.x = this.layout[index].x
          DragPos.y = this.layout[index].y
          DragPos.w = item.w
          DragPos.h = item.h
        }
        if (!mouseInGrid) {
          this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, item.h, item.w)
          this.layout = this.layout.filter((obj) => obj.i !== 'drop')
        }
      }
    },

    dragend(item) {
      const parentRect = document.getElementById('custom-design').getBoundingClientRect()
      const mouseInGrid =
        mouseXY.x > parentRect.left &&
        mouseXY.x < parentRect.right &&
        mouseXY.y > parentRect.top &&
        mouseXY.y < parentRect.bottom
      if (mouseInGrid) {
        this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, DragPos.h, DragPos.w)
        this.layout = this.layout.filter((obj) => obj.i !== 'drop')
        this.layout.push({
          x: DragPos.x,
          y: DragPos.y,
          w: DragPos.w,
          h: DragPos.h,
          i: DragPos.i,
          type: item.type,
          widgetConfig: item.widgetConfig,
        })
        this.$nextTick(() => {
          this.$refs.gridlayout.dragEvent('dragend', DragPos.i, DragPos.x, DragPos.y, DragPos.h, DragPos.w)
        })
        try {
          this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display = 'block'
        } catch {}
      }
  • 写回答

1条回答 默认 最新

  • Leodong. 2023-05-15 09:54
    关注

    该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
    您可以尝试使用requestAnimationFrame(RAF)来优化drag事件,以避免在拖动过程中执行太多的计算和渲染。RAF会在下一帧绘制之前执行回调函数,这可以避免在拖动时导致太多的计算和渲染,并提高性能和流畅度。

    以下是一个示例代码,展示如何使用requestAnimationFrame来优化drag事件:

    dragThrottle(item) {
      let isDragging = false
      let lastTime = 0
      let requestID = null
    
      const handleDrag = () => {
        const currentTime = Date.now()
        if (currentTime - lastTime > 16) { // 限制每秒执行的次数为60
          lastTime = currentTime
          this.drag(item)
        }
    
        if (isDragging) {
          requestID = requestAnimationFrame(handleDrag)
        } else {
          cancelAnimationFrame(requestID)
        }
      }
    
      const dragStartHandler = () => {
        isDragging = true
        handleDrag()
      }
    
      const dragEndHandler = () => {
        isDragging = false
      }
    
      this.$el.addEventListener('dragstart', dragStartHandler, false)
      this.$el.addEventListener('dragend', dragEndHandler, false)
    },
    

    在这个示例代码中,handleDrag函数使用requestAnimationFrame来限制每秒执行的次数,防止在拖动期间执行太多的计算和渲染。在dragstart事件中,启动handleDrag函数,在dragend事件中停止它。

    您可以将这个示例代码适应您的组件和应用程序,以优化您的drag事件并提高性能。


    如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月16日
  • 创建了问题 5月15日

悬赏问题

  • ¥18 关于#贝叶斯概率#的问题:这篇文章中利用em算法求出了对数似然值作为概率表参数,然后进行概率表计算,这个概率表是怎样计算的呀
  • ¥20 C#上传XML格式数据
  • ¥15 elementui上传结合oss接口断点续传,现在只差停止上传和继续上传,各大精英看下
  • ¥100 单片机hardfaulr
  • ¥20 手机截图相片分辨率降低一半
  • ¥50 求一段sql语句,遇到小难题了,可以50米解决
  • ¥15 速求,对多种商品的购买力优化问题(用遗传算法、枚举法、粒子群算法、模拟退火算法等方法求解)
  • ¥100 速求!商品购买力最优化问题(用遗传算法求解,给出python代码)
  • ¥15 虚拟机检测,可以是封装好的DLL,可付费
  • ¥15 kafka无法正常启动(只启动了一瞬间会然后挂了)