移动端触屏事件
移动端的开发经常需要监听用户的touch行为,在移动端主要有以下几个touch事件:
- touchstart 手指触摸屏幕时触发,即使已经有手指在屏幕上也会触发
- touchmove 手指在屏幕滑动时触发
- touchend 手指从屏幕时移开时触发
- touchcancel 当触控点被特定的实现方式打乱时触发(例如,弹框),一般不用
移动端的事件的发生顺序一般是:touchstart---touchmove---touchend,然后大约过300ms会模拟鼠标触发click事件
什么是点击穿透
在发生触摸动作约300ms之后,移动端会模拟产生click动作,它底下的具有点击特性的元素也会被触发,这种现象称为点击穿透。
发生的条件:
上层元素监听了触摸事件,触摸之后该层元素消失
下层元素具有点击特性(监听了click事件或默认的特性(a标签、input、button标签))
解决点击穿透的方法
//点击穿透布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端点击穿透</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
}
#modalBg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.6);
}
.modal {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 300px;
height: 100px;
padding: 20px 0;
background-color: #fff;
text-align: center;
}
.modal p {
margin: 20px 0;
}
.modal button {
font-size: 16px;
padding:10px 20px;
border: 1px solid #ccc;
background: #f5f5f5;
}
.links {
margin-top: 250px;
}
</style>
</head>
<body>
<div class="links"> //下层超链接元素
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
<a href="http://www.baidu.com">百度一下你就知道了</a>
</div>
<div id="modalBg"> //上层元素
<div class="modal">
<p>操作成功</p>
<button id="closeBtn">关闭</button>
</div>
</div>
1、阻止上层元素的默认动作
<script>
(function () {
//获取弹框
var modalBg = document.querySelector('#modalBg');
var closeBtn = document.querySelector('#closeBtn');
//按钮触摸事件 touchend
closeBtn.addEventListener('touchend', function(event){
modalBg.remove();
//阻止默认行为
event.preventDefault();
});
})();
</script>
</body>
</html>
2、全局阻止默认行为
移动端阻止浏览器默认行为的方法:
1、在document元素内阻止,给addEventListener设置第三参数
2、自定义包裹元素,所有的内容都在包裹元素中,在包裹元素中阻止默认行为
addEventListener的第三个参数:
1、布尔值(true/false) 事件是否在捕获阶段触发
2、对象,接受三个属性
{
passive:false, //阻止默认行为
capture:false/true, //事件是否在捕获阶段触发
once:false/true, //事件是否只触发一次
}
//全局阻止默认行为
<script>
(function () {
//获取弹框
var modalBg = document.querySelector('#modalBg');
var closeBtn = document.querySelector('#closeBtn');
//全局阻止默认行为
document.addEventListener('touchstart', function(event){
event.preventDefault();
}, {passive: false});
//按钮触摸事件 touchend
closeBtn.addEventListener('touchend', function(event){
modalBg.remove();
});
//单独给a元素添加 touchend事件
var linkNodes = document.querySelectorAll('.links a');
linkNodes.forEach(function(linkNode){
linkNode.addEventListener('touchend', function(){
location.href = this.href;
});
})
})();
</script>
3、不使用具有点击特性的元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>移动端点击穿透</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
}
#modalBg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.6);
}
.modal {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
width: 300px;
height: 100px;
padding: 20px 0;
background-color: #fff;
text-align: center;
}
.modal p {
margin: 20px 0;
}
.modal button {
font-size: 16px;
padding:10px 20px;
border: 1px solid #ccc;
background: #f5f5f5;
}
.links {
margin-top: 250px;
}
</style>
</head>
<body>
<div class="links"> //下层超链接元素
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
<div href="http://www.baidu.com">百度一下你就知道了</div>
</div>
<div id="modalBg"> //上层元素
<div class="modal">
<p>操作成功</p>
<button id="closeBtn">关闭</button>
</div>
</div>
<script>
(function () {
//获取弹框
var modalBg = document.querySelector('#modalBg');
var closeBtn = document.querySelector('#closeBtn');
//按钮触摸事件 touchend
closeBtn.addEventListener('touchend', function(event){
modalBg.remove();
});
//单独给div元素添加 touchend事件
var linkNodes = document.querySelectorAll('.links div');
linkNodes.forEach(function(linkNode){
linkNode.addEventListener('touchend', function(){
location.href = this.getAttribute('href');
});
})
})();
</script>
4、利用css属性pointer-events
pointer-events属性有很多值,但是对于浏览器来说,只有auto和non两个值可用,其它的几个是针对SVG的(本身这个属性就来自于SVG技术)。
pointer-events属性值详解
- auto——效果和没有定义pointer-events属性相同,鼠标不会穿透当前层。在SVG中,该值和visiblePainted的效果相同。
- none——元素不再是鼠标事件的目标,鼠标不再监听当前层而去监听下面的层中的元素。但是如果它的子元素设置了pointer-events为其它值,比如auto,鼠标还是会监听这个子元素的。
- 其它属性值为SVG专用,这里不再多介绍了。
<script>
(function () {
//获取弹框
var modalBg = document.querySelector('#modalBg');
var closeBtn = document.querySelector('#closeBtn');
var aNodes = document.querySelectorAll('.links a');
//按钮触摸事件 touchend
closeBtn.addEventListener('touchend', function(event){
//使所有的超链接失去点击特性
aNodes.forEach(function(aNode){
aNode.style.pointerEvents = 'none';
});
modalBg.remove();
//当300ms之后,模拟的click动作发生之后,再让超链接具备点击特性
setTimeout(function(){
aNodes.forEach(function(aNode){
aNode.style.pointerEvents = 'auto';
});
}, 350);
});
})();
</script>
5、让上层元素不立即消失,等到模拟click动作约300ms之后再消失
<script>
(function () {
//获取弹框
var modalBg = document.querySelector('#modalBg');
var closeBtn = document.querySelector('#closeBtn');
var aNodes = document.querySelectorAll('.links a');
//按钮触摸事件 touchend
closeBtn.addEventListener('touchend', function(event){
//等一会再消失
setTimeout(function(){
modalBg.remove();
}, 350);
});
})();
</script>
如果对您有帮助的话,点击 http://learn.fuming.site/ 学习更多!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。