触摸移动的工作方式与鼠标移动不同



如果有三个divdiv1、div2、div3并排。如果我在div1上向下移动鼠标,然后将鼠标移动到div2上,那么div2鼠标移动将被触发,目标为div2。但在mobile中,如果在div1上执行相同的操作,甚至mousedown(touchstart(,并将鼠标移动到div2上,那么mousemove(touchmove(将目标作为div1本身进行射击。我需要移动触摸移动事件目标作为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>

这是规范定义的行为:

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

至于为什么这样定义。。。我不太确定,但我认为这可以追溯到iphone在市场上独占鳌头的时候,规格只是接受了它们的行为,认为这可能与我们网络开发人员的直觉相悖

对于我们能做什么,之前已经有人问过并回答过:您可以使用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>

最新更新