在统计按钮点击跳转次数时,给按钮绑定了touchstart事件,结果导致统计数据翻了近10倍。后改用click事件,数据才正常。固有此文。
问题
当我们点击鼠标时,会触发一系列mouse/touch/click事件,a标签转跳是被什么事件触发的?
PC:在 div1 按下鼠标左键, 在div2 中释放鼠标左键,是否会触发click事件?
PC:在 div1 按下鼠标左键后,再在同一绑定事件的节点中移动鼠标,最后释放鼠标左键。 是否会触发click事件?
M: 在 div1 触按屏幕, 再在div2 中释放触按,是否会触发click事件?
M:在 div1 触按屏幕,再在同一绑定事件的节点中移动手指,最后移释放触按。是否会触发click事件?
知道以上5个问题的结果的就可以不往下看了。
demo共用一段html
<a id="a" target="_blank" href="http://www.58.com">58</a>
<div class="div1"></div>
<div class="div2"></div>
1. 当我们点击鼠标时,会触发一系列mouse/touch/pointer事件,a标签转跳是被什么事件触发的?
var events = 'click touchstart touchend mousedown mouseup'.split(' ');
var n = 0;
var timer = setInterval(function(){
var event = new Event(events[n]);
document.getElementById('a').dispatchEvent(event); // 创建一系列事件,直接在元素节点上触发。
console.log(event.type);
n++;
if (n == events.length) {
clearInterval(timer);
}
},2000);
测试结果: a标签跳转 只被 click 事件触发。
2. PC:在 div1 按下鼠标左键, 在div2 中释放鼠标左键,是否会触发click事件?
3.PC:在 div1 按下鼠标左键后,再在同一绑定事件的节点中移动鼠标,最后释放鼠标左键。 是否会触发click事件?
var events = 'click mousedown mouseup'.split(' ');
var divs = document.getElementsByTagName('div');
var handler = function(e){
e.preventDefault();
this.innerHTML += ' type:' + e.type + ' target:' + e.target.className + ' this:' + this.className;
};
for (var i=0; i <divs.length; i++) {
events.forEach(function(event){
divs[i].addEventListener(event, handler);
});
}
测试结果:
问题2、问题3,在相同绑定事件元素中,按下鼠标左键,即使移动也会触发 click 事件,而在不同元素中不会触发 click 事件。
在测试问题3的过程中我们还发现,按下鼠标左键触发的是 div1 绑定的mousedown
事件,释放鼠标左键触发的是 div2 绑定的mouseup
事件。
我们可以这样认为,在点击鼠标左键时,只有在同一元素中先触发mousedown
事件再触发mouseup
事件,click
事件才会被触发,a标签才会转跳
4. M: 在 div1 触按屏幕, 再在div2 中释放触按,是否会触发click事件?
5. M:在 div1 触按屏幕,再在同一绑定事件的节点中移动手指,最后移释放触按。 是否会触发click事件?
var events = 'click touchstart touchend mousedown mouseup'.split(' ');
var divs = document.getElementsByTagName('div');
var handler = function(e){
e.preventDefault();
this.innerHTML += ' type:' + e.type + ' target:' + e.target.className + ' this:' + this.className;
};
for (var i=0; i <divs.length; i++) {
events.forEach(function(event){
divs[i].addEventListener(event, handler); // type:mousedown target:div1 this:div1 | type:mouseup target:div2 this:div2
}); // type:touchstart target:div1 this:div1 | type:touchend target:div1 this:div1
}
测试结果:
问题4,在 div1 触按屏幕, 再在div2 中释放触按,只会触发div1的 touchstart
和 touchend
事件,不会触发div2的 touchend
事件,并且不会触发mousedown
mouseup
click
事件。
问题5,只要移动了手指,mousedown
mouseup
click
事件就不被触发。
如果触摸屏幕,这些事件的触发顺序也是很有趣。
touchstart
-> touchend
-> mousedown
-> mouseup
-> click
。
值得注意的是,touchend
在mousedown
之前被触发。
总结
a标签跳转只被click
事件触发。
在PC端,点击鼠标左键,即使在a标签链接上移动鼠标,也会触发a标签跳转。
在M端,手指触摸屏幕,就会触发a标签跳转,但是如果过程中手指有移动,就触发不了a标签跳转。