如果有三个并排的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(使用前将#替换为@)