与鼠标事件相比,为什么HTML5拖放这么慢

时间:2017-03-29 10:54:27

标签: javascript html5

我想在Angular 2中实现一个可拖动的窗口,我首先在a codepen中尝试了这个。

然而,即使使用普通的JavaScript,与普通的老鼠标事件相比,它似乎也非常慢。

我的示例在Safari上进行了测试,我知道该示例在Chrome / Firefox中不起作用,我认为Chrome会引发额外的错误drag,并且Firefox不会在drag中显示鼠标位置{1}}事件。

此外,该示例在Chrome中运行得更好,产生零到无延迟。我发现reference on StackOverflow说Safari是唯一一个滞后的人。

"use strict"
let el = document.getElementById("window")
let anchor = { x: 0, y: 0 }
let begin = { x: 0, y: 0 }
let newPosition = { x: 0, y: 0 }
let needsRedraw = false

let use = "drag"

if (use == "drag") {
  el.draggable = "true"
  el.addEventListener('dragstart', event => {
    begin = { x: Number.parseInt(el.style.left),
              y: Number.parseInt(el.style.top) }
    anchor = { x: event.clientX, y: event.clientY }
  })
  document.addEventListener('drag', event => {
    let dx = event.clientX - anchor.x
    let dy = event.clientY - anchor.y
    newPosition = { x: begin.x + dx, y: begin.y + dy }

    needsRedraw = true
  })
} else if (use == "click") {
  let moving = false
  el.addEventListener('mousedown', event => {
    moving = true
    begin = { x: Number.parseInt(el.style.left),
              y: Number.parseInt(el.style.top) }
    anchor = { x: event.clientX, y: event.clientY }
  })
  document.addEventListener('mousemove', event => {
    if (moving) {
      let dx = event.clientX - anchor.x
      let dy = event.clientY - anchor.y
      newPosition = { x: begin.x + dx, y: begin.y + dy }
      needsRedraw = true
    }
  })
  document.addEventListener('mouseup', event => {
    moving = false
  })
}

function draw() {
  requestAnimationFrame(draw)
  if (needsRedraw) {
    el.style.left = newPosition.x + "px"
    el.style.top = newPosition.y + "px"
    needsRedraw = false
  }
}

requestAnimationFrame(draw)

1 个答案:

答案 0 :(得分:0)

只使用Angular 2进行测试,我通过ElementRef使用直接元素访问来最小化性能影响。

无论是否有requestAnimationFrame,Chrome都做得更好。但是,如果我关闭Safari的开发者控制台,一切似乎都运行得很顺利。

发现这一切,似乎都不是问题。 (同样限制dragover / drag事件并不能提高性能,因为最大的性能影响是DOM更改,浏览器必须重新绘制元素)