web浏览器中,当我们出现一个浮层,浮层里面也有滚动条的时候,且有部分背景半透明的时候,就会发现,当我们滚动浮层里面的小滚动条的时候,背后整个页面都跟着一起滚走了。
方案1:监听浮层的touchstart,touchmove事件, 计算浮层滚动区域的最大滚动区域,在touchmove事件中判断规则,根据情况阻止默认事件(popup_box_scroll为浮层滚动区域的id)
依赖方法:
let isMy = function(node, id){
return node.getAttribute('id') === id;
},isMyOrParents = function(node, id){
if(isMy(node, id)){
return true;
}else{
let t = node.parentNode;
while(t && !/body/i.test(t.tagName)){
if(isMy(t, id)){
return true;
}
t = t.parentNode;
}
return false;
}
}, ppbData = {
isTarget: false,
posY: 0,
scrollY: 0,
maxscroll: 0
}
给弹出层(id=popup_box)绑定touchstart,touchmove,touchend事件,事件方法如下:
ppbTouchStart: function(e){
let event = e.touches[0] || e;
ppbData.isTarget = isMyOrParents(event.target, 'popup_box_scroll');
// 当前滚动元素标记
ppbData.elScroll = ppbData.isTarget ? document.getElementById('popup_box_scroll') : null;
if(!ppbData.elScroll){
return;
}
// 垂直位置标记
ppbData.posY = event.pageY;
// 现在移动的垂直位置,用来判断是往上移动还是往下
ppbData.scrollY = ppbData.elScroll.scrollTop || ppbData.elScroll.pageYOffset || 0;
// 是否可以滚动
ppbData.maxscroll = ppbData.elScroll.scrollHeight - ppbData.elScroll.clientHeight;
},
ppbTouchMove: function(e){
let event = e.touches[0] || e;
// 如果不足于滚动,则禁止触发整个窗体元素的滚动
if (ppbData.maxscroll <= 0) {
// 禁止滚动
e.preventDefault();
}
if(!ppbData.elScroll){
e.preventDefault();
return;
}
// 移动距离
let distanceY = event.pageY - ppbData.posY;
// 上边缘检测
if (distanceY > 0 && ppbData.scrollY == 0) {
// 往上滑,并且到头
// 禁止滚动的默认行为
e.preventDefault();
}
// 下边缘检测
if (distanceY < 0 && (ppbData.scrollY + 1 >= ppbData.maxscroll)) {
// 往下滑,并且到头
// 禁止滚动的默认行为
e.preventDefault();
}
},
ppbTouchEnd: function(e){
ppbData.isTarget = false;
ppbData.maxscroll = 0;
}
方案2:
给html, body节点设置height=弹出层的高度(弹出层的高度在显示时获取,作防重处理),overflow=hidden样式。