乐趣区

关于前端:学会Pointer指针事件-一套拖拽事件两端PC端移动端跑

晚期浏览器很 low,它只存在鼠标事件(MouseEvent)。随时代的倒退呈现了智能手机、平板电脑等触屏设施,交互方式产生了变动,单纯的鼠标事件已不够开发人员应用了。于是引入了触摸事件(TouchEvent)。不过这还不够完满,没有把触控笔事件思考进去。当要求挪动端、PC 端同时具备拖拽性能时,开发人员还要保护两份事件逻辑。

为了解决上述问题,官网引入了全新的标准 Pointer 指针事件(Pointer),它提供了一套对立的事件,鼠标、触摸、触控笔事件一锅端了,不须要再保护两套事件逻辑。

Pointer 指针事件属性

Pointer 继承 MouseEvent 事件,因而罕用属性 clientX,clientY 等指针事件都具备,同时指针事件也扩大了它本人独有的属性。

属性 介绍
pointerId 指针引起的事件的惟一标识
width 指针的接触面的 CSS 像素宽度
height 指针的接触面的 CSS 像素高度
pressure 指针输出的压力值,范畴在 0 - 1 之间
tangentialPressure 切向压力值,范畴在 -1-1]之间,0 示意管制设施中立状态时的值
tiltX 由输出设施(如手写笔)与 Y 轴的形成立体,和 YZ 立体之间的夹角,范畴在 -90-90 之间
tiltY 由输出设施(如手写笔)与 X 轴形成立体,和 XZ 立体之间的夹角,范畴在 -90-90 之间
twist 输出设施(如手写笔)围绕本身范畴旋转的角度,范畴在 0 -359 之间
pointerType 示意触发事件的设施类型,mouse,pen,touch
isPrimary 示意一个指针是否是以后设施类型的主指针

以上属性应用场景我没想到,有大佬的话能够指导下。

Pointer 事件类型

Pointer 有不同的事件类型,与鼠标事件一样有雷同的语义话示意(down, up, move, over, out, enter, leave)。

事件类型 事件介绍
pointerover 当定点设施进入某个元素的命中检测 范畴时触发。
pointerenter 当定点设施进入某个元素或其子元素的命中检测范畴时,或做为某一类不支悬停(hover)状态的设施所触发的 poinerdown 事件的后续事件时所触发。(详情可见 pointerdown 事件类型).
pointerdown 当某指针得以激活时触发。
pointermove 当某指针扭转其坐标时触发。
pointerup 当某指针不再沉闷时触发。
pointercancel 当浏览器认为某指针不会再生成新的后续事件时触发(例如某设施不再沉闷)
pointerout 可能由若干起因触发该事件,包含:定位设施移出了某命中检测的边界;不反对悬浮状态的设施产生 pointerup 事件(见 pointerup 事件);作为 pointercancel event 事件的后续事件(见 pointercancel 事件);当数位板检测到数位笔来到了悬浮区域时。
pointerleave 当定点设施移出某元素的命中检测边界时触发。对于笔形设施来说,当数位板检测到笔移出了悬浮范畴时触发。
gotpointercapture 当某元素承受到一个指针捕获时触发。
lostpointercapture 当针对某个指针的指针捕获失去开释时触发。

指针、鼠标及触摸事件比照:

MouseEvent TouchEvent PointerEvent
mousedown touchstart pointerdown
mousemove touchmove pointermove
mouseup touchend pointerup
touchcancel pointercancel
mouseenter pointerenter
mouseleave pointerleave
mouseover pointerover
mouseout pointerout
gotpointercapture
lostpointercapture

Pointer 事件的应用

先看看鼠标实现拖拽成果:

<div id="app"></div>
<script>
    const app = document.getElementById('app')
    let isPointerDown = false

    app.addEventListener('mousedown', function (e) {isPointerDown = true});

    document.addEventListener('mousemove', function (e) {if (isPointerDown) {const left = app.getBoundingClientRect().left
            const top = app.getBoundingClientRect().top
            let newLeft = e.clientX - left
            let newTop = e.clientY - top
            console.log(newLeft, newTop);
            app.style.left = newLeft + left - app.clientWidth / 2 + 'px'
            app.style.top = newTop + top - app.clientHeight / 2 + 'px'
        }
    });

    document.addEventListener('mouseup', function (e) {isPointerDown = false});
</script>

电脑、挪动设施别离拜访链接,呈现的成果是电脑能够拖拽,挪动设施不反对。如果想要挪动设施满足拖拽要独自应用触摸事件再写一套。

能够点击这里体验:https://code.juejin.cn/pen/7250291342034042940

用 Pointer 事件实现拖拽:

<div id="app"></div>
<script>
  const app = document.getElementById('app')
  let isPointerDown = false

  app.addEventListener('pointerdown', function (e) {isPointerDown = true});

  app.addEventListener('pointermove', function (e) {
      // 捕捉
      app.setPointerCapture(e.pointerId)
      if (isPointerDown) {const left = app.getBoundingClientRect().left
          const top = app.getBoundingClientRect().top
          let newLeft = e.clientX - left
          let newTop = e.clientY - top
          app.style.left = newLeft + left - app.clientWidth / 2 + 'px'
          app.style.top = newTop + top - app.clientHeight / 2 + 'px'
      }
  });

  app.addEventListener('pointerup', function (e) {isPointerDown = false});
</script>

Pointer 事件与鼠标事件应用存在差别,Pointer 应用 setPointerCapture API 做为捕捉。

应用 Pointer 事件后电脑、挪动设施都能进行拖拽。

能够点击这里体验: https://code.juejin.cn/pen/7250289016656887847

挪动设施拖拽效果图:

总结

Pointer 指针事件帮忙咱们通过一份代码,同时解决鼠标,触摸和触控笔事件,能为开发者节俭掉工夫。防止保护多套事件逻辑,做到一套事件逻辑两端跑。

如果我的文章对你有帮忙,您的👍就是对我的最大反对 ^_^。

往期文章:http://linglan01.cn/about

退出移动版