javascript - touchmove 的工作方式与 mousemove 不同

标签 javascript html

如果有三个并排的div div1,div2,div3。如果我在 div1 上执行 mousedown,然后将鼠标移动到 div2 上,则 div2 mousemove 将被触发,目标为 div2。但在移动设备中,如果在 div1 上执行相同的 mousedown(touchstart) 操作并将鼠标移动到 div2 上,则 mousemove(touchmove) 将以 div1 本身作为目标触发。我需要移动 touchmove 事件目标作为 div2?

为什么行为存在差异以及我们可以做什么?

下面是我用来解释我的问题的示例,

    
            var testString = '';
    
            handleMouseMoveListener = (e) => {
                //console.log(e.target.id);
                e.preventDefault();
                e.stopPropagation();
                this.testString = this.testString + ' ' + e.target.id;
            }
    
            handleMouseUpHandler = (e) => {
    
                alert(this.testString);
                this.testString = '';
            }
    
    
            let elementsArray = document.querySelectorAll("div");
            elementsArray.forEach(function (elem) {
                elem.addEventListener('mousemove', this.handleMouseMoveListener);
                elem.addEventListener('touchmove', this.handleMouseMoveListener);
                elem.addEventListener('mouseup', this.handleMouseUpHandler);
                elem.addEventListener('touchend', this.handleMouseUpHandler);
            });
   <!DOCTYPE html>
    <html>
    <head>
        <title>Page Title</title>
    
        <style>
            div {
                display: inline-block;
                width: 150px;
                height: 150px;
                color: red;
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
    
    
        <div id='div1'>div1</div>
        <div id='div2'>div2</div>
        <div id='div3'>div3</div>
    

    
    </body>
    </html>

最佳答案

这是the specs defined behavior :

The target of this event must be the same Element on which the touch point started when it was first placed on the surface, even if the touch point has since moved outside the interactive area of the target element.

至于为什么这样定义......我不太确定,但我认为这可以追溯到 iphone 在市场上独树一帜的时候,而且规范只是接受了他们的行为,因为这对我们网络开发人员来说是反直觉的可能是这样。

对于我们能做什么,它有 already been asked and answered before :您可以使用 Touch 实例将公开的 clientXclientY 值中的 document.elementFromPoint():

if( document.ontouchmove === undefined ) {
  console.log( "please enable your dev-tools's Responsive mode" );
}

document.querySelectorAll( '.container div' ).forEach( (elem) => {
  elem.addEventListener( 'touchstart', prevent );
  elem.addEventListener( 'touchmove', handleTouchMove );
} );

function handleTouchMove( evt ) {
  //prevent( evt );
  deactivateTarget(); // clean
  
  evt.target.classList.add( 'target' ); // make the official target's text red

  const touch = evt.changedTouches[ 0 ];
  const actualTarget = document.elementFromPoint( touch.clientX, touch.clientY );
  if( actualTarget ) {
    actualTarget.classList.add( 'active' ); // make the hovered element green
  }
}
function deactivateTarget() {
  document.querySelectorAll( '.active,.target' ).forEach( (elem) => {
    elem.classList.remove( 'active', 'target' );
  })  
}

function prevent( evt ) {
  evt.preventDefault();
}
.container div {
  display: inline-block;
  width: 150px;
  height: 50px;
  border: 1px solid black;
}
.container div.active {
  background: green;
}
.container div.target {
  color: red;
}
<div class="container">
  <div>div1</div>
  <div>div2</div>
  <div>div3</div>
  <div>div4</div>
  <div>div5</div>
  <div>div6</div>
  <div>div7</div>
  <div>div8</div>
  <div>div9</div>
  <div>div10</div>
  <div>div11</div>
  <div>div12</div>
  <div>div13</div>
  <div>div14</div>
  <div>div15</div>
</div>

关于javascript - touchmove 的工作方式与 mousemove 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58934867/

相关文章:

javascript - HTML 5音频自定义控件

javascript - 从 @Html.DisplayFor 和 @Html.HiddenFor 获取值

javascript - 如何检查滚动条是否到达div的末尾?

html - 如何制作拉伸(stretch)子项并尊重最小高度 : 0 on them? 的 CSS 网格

c# - 用于 Web 应用程序的开源照片马赛克

javascript - 带有数组的对象

javascript - 使用 jquery 打开对话框

javascript - Aframe:平滑位置和旋转?

javascript - 使用 vue.js 按提交后将用户重定向到不同页面

html - 如何将此标签移动到我的文本区域内?