返回

拒绝滚动穿透,攻克移动端难题

前端

随着移动端市场的份额越来越大,对移动端的需求也变得越来越多样化。今天我们要讨论的正是移动端的滚动穿透问题。上面那句调侃的话可以看出需求中弹窗浮层还是挺常见的,那这个和滚动穿透有什么联系呢?下面我们就来说说我对滚动穿透问题解决方案的探索过程,希望对大家有点启发。

当我接到这个需求时,觉得它并不难,很快就提测了,然后就遇到了意料之中的问题。经过一番排查,我发现问题出在滚动穿透上。为了解决这个问题,我查阅了大量的资料,并结合自己的经验,提出了以下几种解决方案:

  1. 使用position: fixed;将浮层固定在视窗上。这种方法虽然简单有效,但会影响用户体验,因为当用户滚动页面时,浮层不会随着页面滚动而移动。
  2. 使用overflow: hidden;将父元素的滚动条隐藏。这种方法可以解决滚动穿透问题,但会影响父元素的可滚动性,使得用户无法滚动父元素。
  3. 使用touchmove事件来阻止滚动穿透。这种方法需要在父元素上绑定touchmove事件,并在事件处理函数中阻止默认行为。这种方法可以解决滚动穿透问题,但会影响用户体验,因为用户在滚动页面时会遇到阻力。
  4. 使用requestAnimationFrame来控制浮层的滚动。这种方法可以解决滚动穿透问题,并且不会影响用户体验。

经过一番权衡,我最终采用了第四种解决方案。这种方法虽然需要更多的代码,但它可以很好地解决滚动穿透问题,并且不会影响用户体验。

下面是我使用第四种解决方案实现的代码:

var floatEle = document.getElementById('floatEle');
var parentEle = document.getElementById('parentEle');

// 绑定touchmove事件
parentEle.addEventListener('touchmove', function(e) {
  // 阻止默认行为
  e.preventDefault();

  // 获取当前滚动条的位置
  var scrollTop = parentEle.scrollTop;

  // 计算浮层应该滚动的距离
  var scrollDistance = e.touches[0].pageY - floatEle.offsetTop;

  // 设置浮层的滚动位置
  floatEle.scrollTop = scrollDistance;
});

这段代码首先获取了浮层和父元素的DOM元素,然后绑定了touchmove事件。在事件处理函数中,我们阻止了默认行为,并计算了当前滚动条的位置和浮层应该滚动的距离。最后,我们设置了浮层的滚动位置。

通过使用这种方法,我们可以很好地解决滚动穿透问题,并且不会影响用户体验。希望这篇文章对大家有所帮助。