Javascript 指针事件:检测触摸“;透过「;元素

Javascript 指针事件:检测触摸“;透过「;元素,javascript,android,dom,smartphone,pointer-events,Javascript,Android,Dom,Smartphone,Pointer Events,使用指针事件,我找不到合适的事件来触发智能手机上基于手指的触摸(通过Chrome Android和Chrome Devtools的移动仿真进行测试) 我需要的是:当你按住手指在屏幕上移动时,如果触摸动作通过一个元素,就会出现一个“悬停”事件 也就是说,将手指放在元素外部,穿过它,只有在完全穿过元素后才能向上移动手指 我为clearify附加了一个截取的代码:对于蓝色元素我不需要事件,对于代码片段中的红色元素我只需要相应的“in/out”事件。示例JS代码将为鼠标触发,但在移动设备上它不会触发任何

使用指针事件,我找不到合适的事件来触发智能手机上基于手指的触摸(通过Chrome Android和Chrome Devtools的移动仿真进行测试)

我需要的是:当你按住手指在屏幕上移动时,如果触摸动作通过一个元素,就会出现一个“悬停”事件

也就是说,将手指放在元素外部,穿过它,只有在完全穿过元素后才能向上移动手指

我为clearify附加了一个截取的代码:对于蓝色元素我不需要事件,对于代码片段中的红色元素我只需要相应的“in/out”事件。示例JS代码将为鼠标触发,但在移动设备上它不会触发任何console.infos

var elem=document.querySelector(“.element”);
元素addEventListener(“指针覆盖”,函数(){
console.clear();
控制台信息(“指针已触发”);
});
元素addEventListener(“指针引用器”,函数(){
console.clear();
console.info(“指针引用器触发”);
});
元素addEventListener(“pointerleave”,函数(){
console.clear();
console.info(“指针脱离触发”);
});
.outer{
宽度:100px;
高度:100px;
边框:3倍纯色灰色;
字体大小:12px;
颜色:白色;
文本对齐:居中;
触摸动作:无;
}
.开始{
位置:相对位置;
顶部:0px;
左:0px;
宽度:100px;
高度:20px;
背景颜色:蓝色;
}
.元素{
位置:相对位置;
顶部:20px;
左:0px;
宽度:100px;
高度:20px;
背景色:红色;
}
.完{
位置:相对位置;
顶部:40px;
右:0;
宽度:100px;
高度:20px;
背景颜色:蓝色;
}

开始触摸这里
搬过来
到此为止
试试这个

<script>
    var startElem = document.querySelector(".start");
    var endElem = document.querySelector(".end");
    var elem = document.querySelector(".element");

    var started = false;
    var passedThroughStart = false;
    var passedThroughEnd = false;
    var ended = false;

    startElem.addEventListener("pointerdown", function(e){
        started = true;
    });

    window.addEventListener("pointermove", function(e) {
        var x = e.clientX;
        var y = e.clientY;
        var bounds = elem.getBoundingClientRect();

        if( !passedThroughStart &&
            x > bounds.left && x < bounds.left + bounds.width &&
            y > bounds.top && y < bounds.top + bounds.height
        ){
            passedThroughStart = true;
        }

        if( passedThroughStart && !passedThroughEnd &&
            x > bounds.left && x < bounds.left + bounds.width &&
            y > bounds.top + bounds.height
        ){
            passedThroughEnd = true;
        }
    })

    window.addEventListener("pointerup", function(e) {
        var x = e.clientX;
        var y = e.clientY;
        var bounds = endElem.getBoundingClientRect();

        ended = ( x > bounds.left && x < bounds.left + bounds.width && y > bounds.top && y < bounds.top + bounds.height)

        if( started && passedThroughStart && passedThroughEnd && ended ){
            console.log("Hooray!");
        }

        started = false;
        passedThroughStart = false;
        passedThroughEnd = false;
        ended = false;
    });
</script>

我希望我能正确地理解你。我为您编写并测试了两种不同的解决方案:指针事件和触摸事件。在此事件中的每个移动事件中,您可以使用函数检测当前元素

带指针事件的解决方案

也许你可以使用pointerevents——它们可以在Chrome开发工具和移动仿真中使用,但不能在myAndroid设备上使用(我认为我的设备太旧了)。或者您可以将其与指针事件Polyfill一起使用。您可以看到的pointerevents的浏览器兼容性

var elementFromPoint,
isFingerDown=false,
isThroughElemMoved=假,
elem=document.querySelector('.element'),
output=document.querySelector(“#output”);
document.addEventListener('pointerdown',函数(e)
{
if(elem!=e.target)
{
isFingerDown=true;
output.innerHTML='pointer START';
}
});
document.addEventListener('pointermove',函数(e)
{
elementFromPoint=document.elementFromPoint(e.pageX-window.pageXOffset,e.pageY-window.pageYOffset);
if(elem==elementFromPoint)
{
isThroughElemMoved=真;
output.innerHTML='指针移动';
}
});
document.addEventListener('pointerup',函数(e)
{
if(isFingerDown&&isThroughElemMoved&&elem!=elementFromPoint)
output.innerHTML='It is done!';
isFingerDown=isThroughElemMoved=false;
});
.outer
{
宽度:100px;
高度:100px;
边框:3倍纯色灰色;
字体大小:12px;
颜色:白色;
文本对齐:居中;
/*触摸动作:无*/
}
.outer div{位置:相对;左侧:0;高度:20px}
.start{顶部:0;背景:蓝色}
.element{top:20px;background:red}
.end{top:40px;background:blue}

开始触摸这里
搬过来
到此为止



信息
我认为这些活动在手机上根本不起作用。尝试使用
pointermove
当触摸的开始和结束位于红色元素之外时,不会触发
pointermove
pointerover
pointerover
在手机上也不起作用。恐怕你必须手动实现这样的逻辑。我希望我能正确理解你,因为在你的问题中,我们可能会误解任务——没有图像理解任务相对困难。在萨满用手鼓跳舞了很多次之后(很多时间),我为你找到了两个解决方案。@Bharata我认为这不公平,我提供了一个运行片段,可以在dekstop上使用鼠标,但不能在智能手机上运行。我要问的是如何让它在智能手机上工作,所以我想我的问题很清楚。我认为不存在
touchenter/touchleave
。此外,出于其价值,这家伙建议尝试限制触摸处理程序的范围,这样它就不会破坏滚动的破坏性:——但在尝试触摸事件时很好!我特别想要pointerevents,但我也认为我的特定代码示例不适用于触摸事件。请随意提供一个工作示例我已经更新了,但我正在编写一个更简洁的答案OK。。。我想我现在可以用了;)刚刚又更新了答案。我只使用设备模式在chrome上测试过这个,我本来希望避免手动边界框命中测试,但我似乎没有办法。适用于矩形和圆形,但对于非规则元素(我使用SVG…)会变得非常复杂。请接受
elementFromPoint()
的解决方案。这远远优于边界框命中测试,因为它适用于任何SVG形状/路径元素,也适用于没有填充但只有笔划属性的SVG行。
elem.addEventListener('pointenter', function(e) {
    passedThroughStart = true;
}
elem.addEventListener('pointleave', function(e) {
    passedThroughEnd = true;
}