JavaScript中关于触摸交互的'mouseleave'等效方法

14

初步说明:我对js非常陌生,主要通过在网上搜索示例/教程来解决问题。

我正在编写可以在Web和移动设备(例如iPad)上运行的js。

我们有一个库帮助抽象出mousetouch之间的差异:

if (navigator.userAgent.search('Mobile') > 0) {
  window.FLAGS = {
    start: 'touchstart',
    end: 'touchend',
    move: 'touchmove',
    click: 'click',
    touchScreen: true
  };
} else {
  window.FLAGS = {
    start: 'mousedown',
    end: 'mouseup',
    move: 'mousemove',
    click: 'click',
    touchScreen: false
  };
}

然后您可以在代码中执行以下操作:

widget.view.bind(FLAGS.start, function(e) {

我正在尝试找到mouseleavetouch等效方法,以便我可以做出类似的技巧。

我可以想象通过跟踪move上的位置并将其与疑问小部件的边界框进行比较来捕获leave事件的方法,但我希望有一个像touchstart/mousedown关系一样简单的方法。


如果目标是检测触摸失效(即无法再生成点击),则实际上需要检测两个手势。 (1) 触摸可以离开元素,(2) 触摸可以超时。不清楚这个问题是否涵盖了第二种情况,因为 mouseleave 可能被解释为仅涵盖类似鼠标的手势。可以理解,因为第二种情况在2015年至2022年之间显然已经失效。因此,我已经提出了一个新问题来讨论第二种情况。 - personal_cloud
如果目标是检测触摸失效(即无法再生成点击),那么实际上需要检测到两个手势。(1) 触摸可以离开元素,(2) 触摸可以超时。不清楚这个问题是否涵盖了第二种情况,因为mouseleave可能只涵盖了类似鼠标的手势。可以理解,因为第二种情况在2015年至2022年之间显然出现了问题。因此,我已经提出了一个关于第二种情况的新问题 - undefined
3个回答

23

有人提出过这种建议,但据我所知还没有实现:http://www.quirksmode.org/mobile/advisoryTouch.html

像这样的东西可能有效(我从脑海中写下来的,未经测试):

var element;
document.addEventListener('touchstart', function(event) {
    event.preventDefault();
    var touch = event.touches[0];
    element = document.elementFromPoint(touch.pageX,touch.pageY);
}, false);

document.addEventListener('touchmove', function(event) {
    event.preventDefault();
    var touch = event.touches[0];
    if (element !== document.elementFromPoint(touch.pageX,touch.pageY)) {
        touchleave();
    }
}, false);

function touchleave() { 
    console.log ("You're not touching the element anymore");
}

1
谢谢。我认为“未实现”的部分是我需要听到的,我特别感谢提供解决方法的示例代码。 - Doug Banks
1
你的帖子有点过时,但是在touchmove事件中应该使用"changedTouches"而不是"touches"。至少在iPad上,touches数组是未定义的。请参考https://dev59.com/Omw05IYBdhLWcg3wv0V6#7236327进行比较。 - Jörn Berkefeld
如果目标元素也包含嵌套元素,那么if (element !== document.elementFromPoint(touch.pageX,touch.pageY)) { touchleave(); }可能无法正常工作,因为elementFromPoint(x, y)返回包含坐标x、y的最嵌套元素。 - oomer

0

你可能想要查看jQuery touchable插件。


你好,链接已经失效了。请问你能修复一下吗?谢谢。 - Jaime Roman

0
整个触发触摸离开的想法是我们需要获取元素的范围。
例如, 盒子宽度范围从0到实际宽度开始, 盒子高度范围从0到实际高度开始
因此,如果X、Y值在此范围内,则我们在盒子内, 如果不在此范围内,则我们离开了盒子。
请查看此片段以获得更好的澄清。

// select the box that we will leave
const box = document.getElementById('box');

// add touchmove event to the box
box.addEventListener('touchmove', (e) => {
    // stop default behavior
    e.stopPropagation();
    e.preventDefault();
    e = e || window.event;

    // get box properties
    let a = box.getBoundingClientRect();
    // get current width
    let w = a.width;
    // get current height
    let h = a.height;

    // get values on x axis
    const x = e.touches[0].pageX - a.left; // to start the value from 0 (remove offsetleft)
    // get values on y axis
    const y = e.touches[0].pageY - a.top; // to start the value from 0 (remove offsettop)

    //! INFO
    // the box width range starts from [0 : w]
    // the box height range starts from [0 : h]

    // if X values between [0 , w] and Y values between [0 , h] then we inside the box | other than that then we left the box
    if ((x >= 0 && x <= w) && (y >= 0 && y <= h)) {
        console.log('in the box');
    } else {
        console.log('left the box');
    }

});
#box {
    width: 280px;
    height: 280px;
    outline: 1px solid red;
    margin: 100px auto;
}
<div id="box"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接