首页 > 解决方案 > 触摸移动的工作方式与鼠标移动不同

问题描述

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

标签: javascripthtml

解决方案


这是规范定义的行为

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

至于为什么以这种方式定义...我不太确定,但我认为它可以追溯到 iphone 在市场上单独出现的时候,并且规范只是接受了他们的行为,因为这对我们的网络开发人员来说可能是违反直觉的.

对于我们能做什么之前已经被询问和回答:您可以使用您的 Touch 实例将公开document.elementFromPoint()clientX和值:clientY

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>


推荐阅读