cha*_*enu 6 html javascript css touch touch-event
如果您切换放置在上方的元素的高度,则触摸设备上有关于链接的可点击区域的奇怪行为.如果您运行以下代码段(例如,将其保存在本地并使用chrome来模拟触摸事件),您会注意到#mylink在某些情况下您没有点击红色链接区域的哈希值会被添加到网址中.有时你点击红色区域,它不会被添加.
例如
#mylink则会将其添加到URL中,就像您单击红色链接区域一样.=>为什么?#mylink则不会添加到URL.=>为什么?#mylink则不会添加到URL.=>为什么?<html>
<head>
<style type="text/css">
.test {
background: grey;
height: 200px;
}
.test.is-visible {
height: 400px;
}
.link {
height: 600px;
display: block;
background: red;
}
</style>
<script type="text/javascript">
(function() {
window.addEventListener( 'touchstart' , function() {
document.getElementsByClassName("test")[0].classList.toggle('is-visible');
});
})();
</script>
</head>
<body>
<div class="test">
Click the grey area. Element enhances and minimizes itself. Now click on the lower half of the enhanced grey area (if grey = enhanced) or on the white area up to 200px below of the red area (if grey = minimized). #mylink is added to the url as if you had clicked on the red area. Why?
</div>
<a href="#mylink" class="link">The red area is the "normal" click area.</a>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
我在iOS和Android上尝试了这一功能,并在Chrome和Firefox中模拟了触摸事件.他们都表现得一样.
如果我听click的,而不是touchstart或touchend事件,它将按预期工作.
造成这种差异的原因是什么?如果我听触摸事件而不是点击事件,为什么链接区域不同/错位?
长话短说
浏览器在 的位置上发生触摸事件后执行单击事件touchend,无论内容是否由于分配给触摸事件的功能而发生更改。
在深入研究了触摸事件规范之后,我想我可以回答我的问题:
第 8 节描述了触摸事件与鼠标事件和单击的交互。它说:
用户代理可以响应相同的用户输入来调度触摸事件和(...)鼠标事件。
和
如果用户代理将一系列触摸事件解释为点击手势,那么它应该在相应触摸输入的touchend 事件的位置调度 mousemove、mousedown、mouseup 和 click 事件(按此顺序) 。
如果文档的内容在触摸事件的处理期间发生了改变,则用户代理可以将鼠标事件分派到与触摸事件不同的目标。
最重要的是
元素的激活(例如,在某些实现中,点击)通常会产生以下事件序列(尽管这可能略有不同,具体取决于特定的用户代理行为):
1.)触摸启动
2.) 零个或多个 touchmove 事件,具体取决于手指的移动
3.)触摸端
4.) mousemove(为了与遗留的鼠标特定代码兼容)
5.) 鼠标按下
6.) 鼠标松开
7.)单击
因此,总结上面的示例,这意味着:
1.)touchstart或被touchend触发。
2.) 首先处理自定义函数,这会切换类并更改元素的高度/位置。
3.) 之后,click事件在事件发生的同一点执行touch,但现在覆盖不同的目标。
该规范也提供了一种防止这种情况的方法:
如果 touchstart、touchmove 或 touchend 被取消,则用户代理不应分派任何鼠标事件,因为该事件可能是被阻止的触摸事件的结果。
所以我想“修复”此行为的最简单方法是使用“preventDefault()”阻止该事件,然后手动单击事件的目标并最后切换类:
window.addEventListener( 'touchstart' , function(event) {
event.preventDefault();
event.target.click();
document.getElementsByClassName("test")[0].classList.toggle('is-visible');
});
Run Code Online (Sandbox Code Playgroud)
Chromium bug tracker 中的一个声明也证明了这一点。
| 归档时间: |
|
| 查看次数: |
325 次 |
| 最近记录: |