fixed弹出层滚动区域滑动时阻止window窗体的滚动事件
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样式。