touchmove 的工作方式与 mousemove 不同

2024-04-14

如果有三个并排的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>

This is 规范定义的行为 https://www.w3.org/TR/touch-events/#the-touchmove-event:

此事件的目标必须是触摸点首次放置在表面上时启动的同一元素,即使触摸点已移出目标元素的交互区域也是如此。

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

For the 我们可以做什么,它有之前已经被问过并回答过 https://stackoverflow.com/questions/3918842/how-to-find-out-the-actual-event-target-of-touchmove-javascript-event: 您可以使用document.elementFromPoint()来自clientX and clientY您的 Touch 实例将公开的值:

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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

touchmove 的工作方式与 mousemove 不同 的相关文章

随机推荐