PointerEvents:检测“穿过”元素的触摸

Dyn*_*lon 3 javascript android dom smartphone pointer-events

使用指针事件,我找不到正确的事件来触发智能手机上基于手指的触摸(使用 Chrome Android 和 Chrome Devtools 进行移动模拟测试)。

我需要什么:如果您在按住手指在屏幕上移动的同时触摸动作穿过一个元素,则会发生“悬停”事件。

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

我附加了一段代码片段以进行清除:我不需要蓝色元素的事件,我只需要片段中红色元素的相应“输入/输出”事件。示例 JS 代码将为鼠标触发,但在移动设备上它不会触发任何 console.infos。

var elem = document.querySelector(".element");

elem.addEventListener("pointerover", function() {
    console.clear();
    console.info("pointerover triggered");
});
elem.addEventListener("pointerenter", function() {
    console.clear();
    console.info("pointerenter triggered");
});
elem.addEventListener("pointerleave", function() {
    console.clear();
    console.info("pointerleave triggered");
});
Run Code Online (Sandbox Code Playgroud)
.outer {
    width: 100px;
    height: 100px;
    border: 3px solid grey;
    font-size: 12px;
    color: white;
    text-align:center;
    touch-action: none;
    
}

.start {
   position: relative;
   top:0px;
   left:0px;
   width: 100px;
   height: 20px;
   background-color: blue;
}

.element {
   position: relative;
   top: 20px;
   left: 0px;
   width: 100px;
   height: 20px;
   background-color: red;
}

.end {
   position: relative;
   top: 40px;
   right: 0;
   width: 100px;
   height: 20px;
   background-color: blue;
}
Run Code Online (Sandbox Code Playgroud)
<div class="outer">
    <div class="start">Start touch here</div>
    <div class="element">Move over here</div>
    <div class="end">End touch here</div>
</div>
Run Code Online (Sandbox Code Playgroud)

Bha*_*ata 6

我希望我能正确理解你。我为您编写并测试了两种不同的解决方案:pointerevents 和 touch events。在此事件中的每个移动事件中,您可以使用函数检测当前元素document.elementFromPoint()

\n\n

指针事件的解决方案

\n\n

也许你可以使用pointerevents \xe2\x80\x93,它们可以在带有移动模拟的Chrome Devtools中工作,但不能在我的Android设备上工作(我认为我的设备太旧了)。或者您可以将它与 Pointer Events Polyfill 一起使用。您可以在此处查看指针事件的浏览器兼容性。

\n\n

\r\n
\r\n
var elementFromPoint,\r\n    isFingerDown = false,\r\n    isThroughElemMoved = false,\r\n    elem = document.querySelector(\'.element\'),\r\n    output = document.querySelector(\'#output\');\r\n\r\ndocument.addEventListener(\'pointerdown\', function(e)\r\n{\r\n    if(elem != e.target)\r\n    {\r\n        isFingerDown = true;\r\n        output.innerHTML = \'pointer-START\';\r\n    }\r\n});\r\n\r\ndocument.addEventListener(\'pointermove\', function(e)\r\n{\r\n    elementFromPoint = document.elementFromPoint(e.pageX - window.pageXOffset, e.pageY - window.pageYOffset);\r\n\r\n    if(elem == elementFromPoint)\r\n    {\r\n        isThroughElemMoved = true;\r\n        output.innerHTML = \'pointer-MOVE\';\r\n    }\r\n});\r\n\r\ndocument.addEventListener(\'pointerup\', function(e)\r\n{\r\n    if(isFingerDown && isThroughElemMoved && elem != elementFromPoint)\r\n        output.innerHTML = \'It is done!\';\r\n\r\n    isFingerDown = isThroughElemMoved = false;\r\n});
Run Code Online (Sandbox Code Playgroud)\r\n
.outer\r\n{\r\n    width: 100px;\r\n    height: 100px;\r\n    border: 3px solid grey;\r\n    font-size: 12px;\r\n    color: white;\r\n    text-align: center;\r\n    /*touch-action: none*/\r\n}\r\n.outer div{position: relative; left: 0; height: 20px}\r\n.start{top: 0; background: blue}\r\n.element{top: 20px; background: red}\r\n.end{top: 40px; background: blue}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="outer">\r\n    <div class="start">Start touch here</div>\r\n    <div class="element">Move over here</div>\r\n    <div class="end">End touch here</div>\r\n</div>\r\n<br><br>\r\n<div id="output">info</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

触摸事件的解决方案

\n\n

但您也可以使用触摸事件。不幸的是,事件touchentertouchleave已从规范中删除,因此我们document.elementFromPoint()也必须使用它们编写一个解决方法。

\n\n

以下代码片段仅适用于移动模拟(使用 Chrome Devtools 测试)或支持触摸事件的设备(使用 Android 测试)。

\n\n

\r\n
\r\n
var elementFromPoint,\r\n    isFingerDown = false,\r\n    isThroughElemMoved = false,\r\n    elem = document.querySelector(\'.element\'),\r\n    output = document.querySelector(\'#output\');\r\n\r\ndocument.addEventListener(\'touchstart\', function(e)\r\n{\r\n    if(elem != e.target)\r\n    {\r\n        isFingerDown = true;\r\n        output.innerHTML = \'touch-START\';\r\n    }\r\n});\r\n\r\ndocument.addEventListener(\'touchmove\', function(e)\r\n{\r\n    var touch = e.touches[0];\r\n    \r\n    elementFromPoint = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset);\r\n\r\n    if(elem == elementFromPoint)\r\n    {\r\n        isThroughElemMoved = true;\r\n        output.innerHTML = \'touch-MOVE\';\r\n    }\r\n});\r\n\r\ndocument.addEventListener(\'touchend\', function(e)\r\n{\r\n    if(isFingerDown && isThroughElemMoved && elem != elementFromPoint)\r\n        output.innerHTML = \'It is done!\';\r\n\r\n    isFingerDown = isThroughElemMoved = false;\r\n});
Run Code Online (Sandbox Code Playgroud)\r\n
.outer\r\n{\r\n    width: 100px;\r\n    height: 100px;\r\n    border: 3px solid grey;\r\n    font-size: 12px;\r\n    color: white;\r\n    text-align: center;\r\n    /*touch-action: none*/\r\n}\r\n.outer div{position: relative; left: 0; height: 20px}\r\n.start{top: 0; background: blue}\r\n.element{top: 20px; background: red}\r\n.end{top: 40px; background: blue}
Run Code Online (Sandbox Code Playgroud)\r\n
<div class="outer">\r\n    <div class="start">Start touch here</div>\r\n    <div class="element">Move over here</div>\r\n    <div class="end">End touch here</div>\r\n</div>\r\n<br><br>\r\n<div id="output">info</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n\n

也许以下链接可以帮助您:

\n\n\n