ios 内嵌h5页面遇到的兼容问题

943 阅读3分钟

需求是做这样一个页面

页面结构.png

1.按钮点击无反应,加cursor pointer

问题: 当委托给一个元素添加click事件时,如果事件是委托到 document 或 body 上,并且委托的元素是默认不可点击的(如 div, span 等),此时 click 事件会失效。

解决: 给目标元素加一条样式规则 cursor: pointer;

2.部分刘海屏手机高度计算问题

在 iphone X 之后引入了一个新概念:“safe area(安全区域)”,安全区域指屏幕内不受圆角、齐刘海、底部小黑条等元素影响的可视窗口。 适配方法:

步骤一:

<meta name="viewport" content="viewport-fit=cover"> //让页面充满全屏

步骤二:在样式文件中加入

body{
  padding-top: constant(safe-area-inset-top); /* iOS 11.0 */
  padding-top: env(safe-area-inset-top); /* iOS 11.2 */   
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: constant(safe-area-inset-left);
  padding-left: env(safe-area-inset-left);
  padding-right: constant(safe-area-inset-right);
  padding-right: env(safe-area-inset-right);
}

@supports ((height: constant(safe-area-inset-top)) or (height: env(safe-area-inset-top))) and (-webkit-overflow-scrolling: touch) {
  .fullscreen {
    /* 适配齐刘海 */
    padding-top: 20px;
    padding-top: constant(safe-area-inset-top);
    padding-top: env(safe-area-inset-top);
    
    /* 适配底部小黑条 */
    padding-bottom: 0;
    padding-bottom: costant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
  }
}

@supports (-webkit-overflow-scrolling: touch) {
  /* 适配ios 非齐刘海机型 */
}

:root {
  --sat: env(safe-area-inset-top);
  --sar: env(safe-area-inset-right);
  --sab: env(safe-area-inset-bottom);
  --sal: env(safe-area-inset-left);
}

步骤三:这时就能在js文件中获取安全区域高度了

getComputedStyle(document.documentElement).getPropertyValue("--sab")

3.上拉下拉空白问题

表现: 手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。 解决:

var ua = navigator.userAgent.indexOf('iPhone');//判断是否为ios
if(ua >-1){
    //ios下运行
    var divEl = document.querySelector('.scroll_content')//你需要滑动的dom元素
    iosTouchFn(divEl);
}
// ios滑动事件
function iosTouchFn(el) {
    //el需要滑动的元素
    el.addEventListener('touchmove',function(e){
        e.isScroller = true;
    })
    document.body.addEventListener('touchmove',function(e){
        if(!e.isScroller){
            e.preventDefault(); //阻止默认事件(上下滑动)
        }else{
            //需要滑动的区域
            var top = el.scrollTop; //对象最顶端和窗口最顶端之间的距离
            var scrollH = el.scrollHeight; //含滚动内容的元素大小
            var offsetH = el.offsetHeight; //网页可见区域高
            var cScroll = top + offsetH; //当前滚动的距离

            //被滑动到最上方和最下方的时候
            if (top == 0) {
                el.scrollTop = 1; //0~1之间的小数会被当成0
            }else if(cScroll === scrollH){
                el.scrollTop = top - 1;
            }
        }
    }, {passive: false}) //passive防止阻止默认事件不生效
}

4.软键盘遮挡输入框问题

原因: 在ios中,软键盘在页面最上层,软键盘的弹起不会引起窗口高度的变化,故而会遮挡原本处于最底部的输入框。

但是在android下,软键盘与窗口处于同一层,所以当软键盘弹起时,当前窗口会发生变化,故而不存在这个问题。

没找到好的解决方案,只能预留出软键盘的高度

注意: 预留出键盘高度要注意区分ios和安卓。只有ios需要预留

判断是否是IOS的方法(IOS浏览器,如果要判断app,需要提供一个原生方法来判断)

var isIOS=false
if(navigator.userAgent.indexOf("iPhone")>-1){
    isIOS=true
}

5.弹窗遮罩层下方还能滚动问题

ios滑动穿透

解决: 当弹窗出现的时候, 给body添加固定定位

body{  
position:fixed;  
top:0;left:0;right:0;bottom:0;  
}

6.页面滚动时改变滚动条位置,页面空白问题。

原因:-webkit-overflow-scrolling:touch; 由于使用-webkit-overflow-scrolling这个属性,苹果手机会使用硬件加速,从而促使页面滑动得更加流畅,然而也导致了页面出现空白的情况。

解决: 滚动之前,先设-webit-overflow-scrolling的属性值为auto,然后页面滚动完了,再设为touch即可。

$(".scroll_content").css('-webkit-overflow-scrolling','auto');
$(".scroll_content").scrollTop(0)
$(".scroll_content").css('-webkit-overflow-scrolling','scroll');