解决ios移动端双滚动条导致滚动穿透问题

本文提供了多种解决滚动穿透问题的方法,包括在弹出层的touchstart和touchmove事件中调用preventDefault,通过CSS设置overflow属性,以及使用JavaScript实现更复杂的解决方案,确保在不同设备和浏览器上的一致体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解决方案1

在弹出层的touchstart事件中调用preventDefault

这种方法不可取,至少有3个缺点:

  1. 如果弹出层本身是有滚动(条)的话,将会导致弹出层无法滚动,此时用这种方法无异于饮鸩止渴。
  2. 一个很常见的场景,点击弹出层,弹出层消失掉,此时也无法触发弹出层的点击回调事件。
  3. 弹出层内的任何事件都执行不了了。

 

解决方案2

此解决方案是解决方案1的升级版。

在弹出层的touchmove(注意区别)事件中调用preventDefault

这种解决办法没有了第一种解决办法的 2, 3 缺点。适用于弹出层本身有没有滚动(条)。

 

解决方案3

设置body{overflow:hidden;}

缺点:经测试,在PC上支持良好,但是在IOS端,跟没有设置是一样的,完全不起任何作用!。

这种解决方案适用于PC端。

 

解决方案4

设置 html,body{overflow:hidden;}

在PC和移动端都能禁止掉下层的滚动。

缺点:

  1. 滚动位置丢失!页面会回到顶部!
  2. 页面的背景还是能够有滚的动的效果(这个我没遇到)。

可通过js来fix这个缺点,在弹出层出现时,记录页面的scrollTop,当弹出层消失时,把先前记录的scrollTop再次赋予页面。

 

终极完美解决方案

此解决方案能够避免上述所有缺点。堪称完美。

(这个方案会导致主页面display:flex 的元素在弹框打开后消失)

css

body.dialog-open {
  position: fixed;
  width: 100%;
}

javascript

(function(){

   var scrollTop = 0;

   // 显示弹出层
   open.onclick = function(){
      
      // 在弹出层显示之前,记录当前的滚动位置
      scrollTop = getScrollTop();
        
      // 使body脱离文档流
      document.body.classList.add('dialog-open'); 
      
      // 把脱离文档流的body拉上去!否则页面会回到顶部!
      document.body.style.top = -scrollTop + 'px';
    
      mask.style.display = 'block';
   }  

   // 隐藏弹出层
   close.onclick = function(){

     mask.style.display = 'none';
     
     // body又回到了文档流中(我胡汉三又回来啦!)
     document.body.classList.remove('dialog-open');
 
     // 滚回到老地方
     to(scrollTop);
   }

   function to(scrollTop){
     document.body.scrollTop = document.documentElement.scrollTop = scrollTop;
   }
   function getScrollTop(){
     return document.body.scrollTop || document.documentElement.scrollTop;
   }

 }()); 

 

解决滚动穿透的2个工具方法:

function fixedBody(){
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    document.body.style.cssText += 'position:fixed;top:-'+scrollTop+'px;';
}

function looseBody() {
    var body = document.body;
    body.style.position = '';
    var top = body.style.top;
    document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top);
    body.style.top = '';
}

 

在使用 `Element UI` 的 `el-input` 和 `el-textarea` 组件时,若组件被包裹在具有滚动区域的容器中,可能会出现输入框边框被滚动条遮挡的问题。该问题通常由层级(z-index)、容器溢出(overflow)设置或组件样式穿透处理当引起。 ### 问题分析 当 `el-input` 或 `el-textarea` 被嵌套在设置了 `overflow: auto` 或 `overflow: scroll` 的容器中时,其内部生成的 `.el-input__inner` 或 `.el-textarea__inner` 元素可能因父容器的裁剪行为导致部分边框可见。此外,某些浏览器(如移动端浏览器)对表单元素的默认渲染方式也可能加剧这一问题[^1]。 ### 解决方案 为了解决边框被滚动条遮挡的问题,可以从以下几个方面入手: #### 1. 调整容器的 `overflow` 行为 避免直接在包含输入框的父容器上使用 `overflow: scroll`。可以尝试将输入框移出滚动区域,或者使用 `overflow: visible` 来防止裁剪。 ```css .inputContainer { overflow: visible; } ``` #### 2. 增加 `z-index` 层级控制 确保 `el-input` 和 `el-textarea` 内部元素的 `z-index` 高于滚动条或其他遮挡元素,从而保证边框会被裁剪。 ```css .inputDeep >>> .el-input__inner, .inputDeep >>> .el-textarea__inner { position: relative; z-index: 2; } ``` #### 3. 使用 `transform` 强制提升渲染层级 通过添加 `transform` 属性,可以触发 GPU 加速并提升元素的渲染优先级,有助于避免边框被截断。 ```css .inputDeep >>> .el-input__inner, .inputDeep >>> .el-textarea__inner { transform: translateZ(0); } ``` #### 4. 样式穿透与兼容性调整 对于 `el-textarea`,除了隐藏边框外,还需注意 `resize` 属性可能导致的布局异常。将其设为 `none` 可以避免用户手动拉伸带来的视觉干扰[^1]。 ```css .inputDeep >>> .el-textarea__inner { resize: none; } ``` #### 5. 检查并重置默认样式 在某些 iOS 设备上,原生 `input` 元素的默认样式可能影响自定义样式显示效果。可以通过重置默认外观来避免此类问题[^3]。 ```css .inputDeep >>> .el-input__inner { -webkit-appearance: none; border-radius: 0; } ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值