移动端H5常见兼容问题

1. 1px边框问题解决方案

1.1 上边框或者下边框

.item-css3transform::after {
  content: '';
  display: block;
  height: 1px;
  transform: scaleY(0.5);
  background: #ccc;
  position: relative;
  top: 10px;
}

&::after {
  content: " ";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  bottom: 0;
  border-bottom: 1px solid #cdcdcd;
  -webkit-transform-origin: 0 100%;
  transform-origin: 0 100%;
  -webkit-transform: scaleY(.5);
 }

1.2 四个边框的情况,圆角需要加背景颜色,父子级元素加圆角属性

 .register-input {
      padding-top: 1.1rem;
      width: 6rem;
      .phone-main,.msg-main {
        position: relative;
        z-index: 2;
        box-sizing: border-box;
        height: 0.9rem;
        font-size: 0.28rem;
        border-radius: 16px;
        width: 100%;
        background:#fff;
        &::after {
          pointer-events: none;
          box-sizing: border-box;
          display: block;
          content:"";
          position: absolute;
          z-index: -1;
          left:0;
          top:0;
          width: 200%;
          height: 200%;
          border: 1px solid #aeaeae;
          background:#fff;
          border-radius: 16px;
          -webkit-transform: scale(0.5);
          transform: scale(0.5);
          -webkit-transform-origin: left top;
          transform-origin: left top;
        }
        .code-input, .phone-input {
          position: relative;
          z-index: 2;
          top: 1px;
          left: 1px;
          height: 0.86rem;
          font-size: 0.28rem;
          text-indent: 0.2rem;
          border-radius: 16px;
          border: none;
          background: transparent;
          &::placeholder {
            font-size: 0.28rem;
            line-height: 0.29rem;
            color: #b5b5b5;
          }
        }
      }

2. boder-radius: 50% 安卓手机兼容问题

2.1 在安卓手机 boder-radius:50%不是全圆

把元素rem宽高改为px,或者把rem的值先放大一倍,再用scale缩小

.box{
    width:7px;
    height:7px;
    border-radius:50%; 
}

.box {
     width:.28rem;
     height:.28rem;
    border-radius:50%;
    transform: scale(.5);
    transform-origin: 0% center;
}

2.2 Android 2.3 自带浏览器不支持 %

Android 2.3 是不支持百分比的,要兼容我们只能使用一个较大值,比如border-radius: 999px;

2.3 Android 4.2.x 背景色溢出

测试发现,在 Android 4.2.x 系统自带浏览器中,同时设置border-radius和背景色的时候,背景色会溢出到圆角以外部分,需要是使用background-clip: padding-box;来修复,但是如果border-color为半透明时,背景直角部分依然会露出来(参见图一)。

关于背景剪裁background-clip
css 代码:
background-clip: border-box|padding-box|content-box;
值描述测试border-box背景被裁剪到边框盒。测试padding-box背景被裁剪到内边距框。测试content-box背景被裁剪到内容框。测试

用box-shadow模拟边框
背景色溢出另一个解决办法就是使用box-shadow模拟border;差不多可以达到效果
比如
box-shadow: 0 0 1px 1px #333333;
border: 1px solid #333333;

2.4 Android 4.2.x 不支持border-radius缩写

 这个 BUG在小米上测试并未发现,国外有人反映三星 Galaxy S4 中自带浏览器不支持。
 解决方案就是使用border-radius的四个扩写属性,缩写属性放到最后。

.foo {
    width: 100px;
    height: 100px;
    border: 5px solid blue;
    border-top-left-radius: 999px; /* 左上角 */
    border-top-right-radius: 999px; /* 右上角 */
    border-bottom-right-radius: 999px; /* 右下角 */
    border-bottom-left-radius: 999px; /* 左下角 */
    border-radius: 999px;
    background-color: #ccc;
    background-clip: padding-box;
}

2.5 css3中用border-radius画出的圆在手机有毛边

给元素加overflow:hidden

3. ios端兼容input光标高度

问题详情描述:input输入框光标,在安卓手机上显示没有问题,但是在苹果手机上
当点击输入的时候,光标的高度和父盒子的高度一样。例如下图,左图是正常所期待的输入框光标,右边是ios的input光标。

出现原因分析:通常我们习惯用height属性设置行间的高度和line-height属性设置行间的距离(行高),当点击输入的时候,光标的高度就自动和父盒子的高度一样了。(谷歌浏览器的设计原则,还有一种可能就是当没有内容的时候光标的高度等于input的line-height的值,当有内容时,光标从input的顶端到文字的底部

解决办法:高度height和行高line-height内容用padding撑开


.content{
  float: left;
  box-sizing: border-box;
  height: 88px;
  width: calc(100% - 240px);              
  .content-input{
    display: block;
    box-sizing: border-box;
    width: 100%;
    color: #333333;
    font-size: 28px;
    //line-height: 88px;
    padding-top: 20px;
    padding-bottom: 20px;
  }
 }

4. ios端微信h5页面上下滑动时卡顿、页面缺失

问题详情描述:在ios端,上下滑动页面时,如果页面高度超出了一屏,就会出现明显的卡顿,页面有部分内容显示不全的情况,例如下图,右图是正常页面,边是ios上下滑动后,卡顿导致如左图下面部分丢失。

出现原因分析:
笼统说微信浏览器的内核,Android上面是使用自带的WebKit内核,iOS里面由于苹果的原因,使用了自带的Safari内核,Safari对于overflow-scrolling用了原生控件来实现。对于有-webkit-overflow-scrolling的网页,会创建一个UIScrollView,提供子layer给渲染模块使用。【有待考证】

解决办法:只需要在公共样式加入下面这行代码

*{
  -webkit-overflow-scrolling: touch;
}

But,这个属性是有bug的,比如如果你的页面中有设置了绝对定位的节点,那么该节点的显示会错乱,当然还有会有其他的一些bug。

拓展知识: -webkit-overflow-scrolling:touch是什么?

MDN上是这样定义的:

-webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效果.
auto: 使用普通滚动, 当手指从触摸屏上移开,滚动会立即停止。

touch: 使用具有回弹效果的滚动, 当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。

5. ios键盘唤起,键盘收起以后页面不归位

问题详情描述:
输入内容,软键盘弹出,页面内容整体上移,但是键盘收起,页面内容不下滑

出现原因分析:
固定定位的元素 在元素内 input 框聚焦的时候 弹出的软键盘占位 失去焦点的时候软键盘消失 但是还是占位的 导致input框不能再次输入 在失去焦点的时候给一个事件

解决办法:

投·被保险人姓名

拓展知识: position: fixed的元素在ios里,收起键盘的时候会被顶上去,特别是第三方键盘

6. 安卓弹出的键盘遮盖文本框

问题详情描述:
安卓微信H5弹出软键盘后挡住input输入框,如下左图是期待唤起键盘的时候样子,右边是实际唤起键盘的样子

出现原因分析:待补充
解决办法:给input和textarea标签添加focus事件,如下,先判断是不是安卓手机下的操作,当然,可以不用判断机型,Document 对象属性和方法,setTimeout延时0.5秒,因为调用安卓键盘有一点迟钝,导致如果不延时处理的话,滚动就失效了

    changefocus(){
      let u = navigator.userAgent, app = navigator.appVersion;
      let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
      if(isAndroid){
        setTimeout(function() {
         document.activeElement.scrollIntoViewIfNeeded();
         document.activeElement.scrollIntoView();
        }, 500);       
      }
    },

拓展知识:
Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。而Element.scrollIntoViewIfNeeded()方法也是用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。但如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动


// 键盘弹出后挡表单的解决方案

window.addEventListener('resize', function () {
    if (
      document.activeElement.tagName === 'INPUT' ||
      document.activeElement.tagName === 'TEXTAREA' ||
      document.activeElement.getAttribute('contenteditable') == 'true'
    ) {
      window.setTimeout(function () {
        if ('scrollIntoView' in document.activeElement) {
          document.activeElement.scrollIntoView();
        } else {
        
          document.activeElement.scrollIntoViewIfNeeded();
        }
      }, 0);
    }
})

7. Vue中路由使用hash模式,开发微信H5页面分享时在安卓上设置分享成功,但是ios的分享异常

问题详情描述:
ios当前页面分享给好友,点击进来是正常,如果二次分享,则跳转到首页;使用vue router跳转到第二个页面后在分享时,分享设置失败;以上安卓分享都是正常

出现原因分析:jssdk是后端进行签署,前端校验,但是有时跨域,ios是分享以后会自动带上 from=singlemessage&isappinstalled=0 以及其他参数,分享朋友圈参数还不一样,貌似系统不一样参数也不一样,但是每次获取url并不能获取后面这些参数

解决办法:

(1) 可以使用改页面this.$router.push跳转,为window.location.href去跳转,而不使用路由跳转,这样可以使地址栏的地址与当前页的地址一样,可以分享成功(适合分享的页面不多的情况下,作为一个单单页运用,这样刷新页面跳转,还是..)

(2)把入口地址保存在本地,等需要获取签名的时候 取出来,注意:sessionStorage.setItem(‘href’,href); 只在刚进入单应用的时候保存!【该方法未验证】

8. 其他问题

8.1 ios和android下触摸元素时出现半透明灰色遮罩

   a,button,input,textarea{
    -webkit-tap-highlight-color: rgba(0,0,0,0)
    -webkit-user-modify:read-write-plaintext-only;
}

android用户点击一个链接,会出现一个边框或者半透明灰色遮罩, 不同生产商定义出来额效果不一样,可设置-webkit-tap-highlight-color的alpha值为0去除部分机器自带的效果

-webkit-user-modify有个副作用,就是输入法不再能够输入多个字符·
另外,有些机型去除不了,如小米2

对于按钮类还有个办法,不使用a或者input标签,直接用div标签

8.2 IOS 默认输入框内阴影重置


/*E:这个是代指字符,实际自己替换,ID,CLASS,TAG*/
   E{
     border: 0;  
     -webkit-appearance: none; 
  }

8.3 旋转屏幕时,字体大小调整的问题

html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {
-webkit-text-size-adjust:100%;
}

8.4 transition闪屏

/设置内嵌的元素在 3D 空间如何呈现:保留3D /
-webkit-transform-style: preserve-3d;
/ 设置进行转换的元素的背面在面对用户时是否可见:隐藏 /
-webkit-backface-visibility:hidden;
开启硬件加速
解决页面闪白
保证动画流畅
.css {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}

8.5 placeholder的颜色值改变

input::-webkit-input-placeholder{color:#F40;}
input:focus::-webkit-input-placeholder{color:#F40;}

8.6 移动端禁止选中内容

E {
-webkit-user-select: none; /* Chrome all / Safari all /
-moz-user-select: none; /
Firefox all (移动端不需要) /
-ms-user-select: none; /
IE 10+ */
}

8.7 IOS禁止保存或拷贝图像

长按图片保存场景下,禁止IOS默认识别图像行为

img { -webkit-touch-callout: none; }

8.8 IOS中input键盘事件调用缓慢

直接改为监听input事件
document.getElementById('test').addEventListener('input',fn,false);

8.9 页面高度渲染错误

document.documentElement.style.height = window.innerHeight + 'px';

8.10 怪异悬浮的表单

在部分android 机型中的输入框可能会出现如图怪异的多余的浮出表单,经过观察与测试发现只有input:password类型的输入框存在,那么我们只要使用input:text类型的输入框并通过样式-webkit-text-security: disc; 隐藏输入密码从而解决。

input[type=text]{
-webkit-text-security: disc;
}

8.11 取消input在ios下,输入的时候英文首字母的默认大写


8.12 android 上去掉语音输入按钮

input::-webkit-input-speech-button {display: none}

9. 其他一些建议

能用transform实现的过渡的,可以不考虑animation实现;animation在部分机子过渡非常掉帧,体验非常糟糕,遇到过好几次

页面有滚动区域的建议引入iscroll5,可以避免很多天坑

页面应该尽可能的减少复杂的DOM【一个功能点,DOM结构越直白,越好维护】,复杂DOM会增加维护难度

考虑移动端响应布局,建议引入阿里巴巴出品的lib-flexible , IOS动态调整DPR,其他设备默认DPR1

点透事件可以引入fastclick或者不用click,改为touch来写,亦或者引入zepto的tap事件

你可能感兴趣的:(移动端H5常见兼容问题)