俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

移动端兼容性问题解决方案

问题

如图一个表单:

俄罗斯贵宾会 1

在部分android机型上测试点击靠下的输入框时遇到弹出的软键盘挡住输入框问题,ios可自身弹起(ios自身的调整偶尔也会出问题,例如第三方键盘会遮挡,原因是第三方输入法的tool bar或者键盘也被当做可视区域,这里不做讨论)

1. IOS移动端click事件300ms的延迟响应

移动设备上的web网页是有300ms延迟的,玩玩会造成按钮点击延迟甚至是点击失效。这是由于区分单击事件和双击屏幕缩放的历史原因造成的,

2007年苹果发布首款iphone上IOS系统搭载的safari为了将适用于PC端上大屏幕的网页能比较好的展示在手机端上,使用了双击缩放(double tap to zoom)的方案,比如你在手机上用浏览器打开一个PC上的网页,你可能在看到页面内容虽然可以撑满整个屏幕,但是字体、图片都很小看不清,此时可以快速双击屏幕上的某一部分,你就能看清该部分放大后的内容,再次双击后能回到原始状态。

双击缩放是指用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。

原因就出在浏览器需要如何判断快速点击上,当用户在屏幕上单击某一个元素时候,例如跳转链接<a href="#"></a>,此处浏览器会先捕获该次单击,但浏览器不能决定用户是单纯要点击链接还是要双击该部分区域进行缩放操作,所以,捕获第一次单击后,浏览器会先Hold一段时间t,如果在t时间区间里用户未进行下一次点击,则浏览器会做单击跳转链接的处理,如果t时间里用户进行了第二次单击操作,则浏览器会禁止跳转,转而进行对该部分区域页面的缩放操作。那么这个时间区间t有多少呢?在IOS safari下,大概为300毫秒。这就是延迟的由来。造成的后果用户纯粹单击页面,页面需要过一段时间才响应,给用户慢体验感觉,对于web开发者来说是,页面js捕获click事件的回调函数处理,需要300ms后才生效,也就间接导致影响其他业务逻辑的处理。

解决方案:

fastclick可以解决在手机上点击事件的300ms延迟

zepto的touch模块,tap事件也是为了解决在click的延迟问题

触摸事件的响应顺序为 touchstart --> touchmove --> touchend --> click,也可以通过绑定ontouchstart事件,加快对事件的响应,解决300ms延迟问题

问题分析及解决办法确立

最常见的是使用两个方法:scrollIntoViewIfNeeded()scrollIntoView(),使用方法自行百度。在我这里无效。

2.一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发,css增加cursor:pointer就搞定了。

经测试发现android弹出键盘时有两种效果:

1.将activity挤压,键盘也占一部分activity空间;

2.键盘弹出在浏览器上面覆盖一层,不影响浏览器大小。

第二种会出现遮挡问题

3. 三星手机遮罩层下的input、select、a等元素可以被点击和focus(点击穿透)

问题发现于三星手机,这个在特定需求下才会有,因此如果没有类似问题的可以不看。首先需求是浮层操作,在三星上被遮罩的元素依然可以获取focus、click、change),有两种解决方案,

1.是通过层显示以后加入对应的class名控制,截断显示层下方可获取焦点元素的事件获取

2.是通过将可获取焦点元素加入的disabled属性,也可以利用属性加dom锁定的方式(disabled的一种变换方式)

俄罗斯贵宾会,于是想到以下两种方案:

1.通过动态增加页面高度设置scrollTop来使输入框到达合适的位置

2.设置相对定位,通过top来使输入框到达合适的位置

4. h5底部输入框被键盘遮挡问题

h5页面有个很蛋疼的问题就是,当输入框在最底部,点击软键盘后输入框会被遮挡。可采用如下方式解决

俄罗斯贵宾会 2

var oHeight = $(document).height(); //浏览器当前的高度

   $(window).resize(function(){

        if($(document).height() < oHeight){

        $("#footer").css("position","static");
    }else{

        $("#footer").css("position","absolute");
    }

   });

  关于Web移动端Fixed布局的解决方案,这篇文章也不错

http://efe.baidu.com/blog/mobile-fixed-layout/

俄罗斯贵宾会 3

影响实现的两个点:

1.js拿不到键盘的弹出和收起事件;

2.覆盖一层的键盘弹出方式不会触发window.resize事件和onscroll事件。

5.不让 Android 手机识别邮箱

<meta content="email=no" name="format-detection" />

解决

第一种经试验有些问题影响了实现,这里只讨论第二种。

直接上代码,这里是react项目(css设置absolute配合js改变top实现效果,transition过渡增强用户体验,这里就不放了)

  getElementOffsetTop(el) {
    let top = el.offsetTop
    let cur = el.offsetParent
    while(cur != null){
          top += cur.offsetTop
          cur = cur.offsetParent
   }
   return top
  }

  componentDidMount() {
    const u = navigator.userAgent
    const isAndroid=u.indexOf('Android')>-1||u.indexOf('Linux')>-1;//android终端
    // alert('android'+isAndroid)
    if(isAndroid){ // android统一处理,不影响ios的自身处理
      const body = document.getElementsByTagName('body')[0] // 兼容获取body

      const regDom = document.querySelector('.wrapper_register') // 获取页面根元素
      const content = document.querySelector('.content') // 表单内容部分

      // const scrollHeight = body.scrollHeight // 网页文档高
      // const scrollTop = body.scrollTop// 卷上去的高

      const clientHeight = body.clientHeight //可见高
      const fixHeight = clientHeight/3 // 定位高,弹出键盘时input距浏览器上部的距离,自己定义合适的

      // 符合需弹出键盘的元素query
      const queryStr = 'input[type="text"], input[type="tel"], input[type="password"], textarea'
      const inputs = content.querySelectorAll(queryStr)

      // console.log(inputs)

      const offsetTopArr = Array.prototype.map.call(inputs,item=>{
        return this.getElementOffsetTop(item) // offsetTop只能获取到顶部距它的offsetParent的距离,需此方法获取到元素距顶部的距离
      })

      inputs.forEach((item, i)=>{
        item.addEventListener('focus',()=>{
          // 改变top上移页面
          regDom.style.top = '-' + (offsetTopArr[i] - fixHeight) + 'px'
        })

        item.addEventListener('blur',()=>{
          // 恢复top
          regDom.style.top = 0
        })
      })
    }
  }

效果基本实现,这里还有两个问题:

第一,如果下面的提交按钮是fixed,有些手机键盘弹出时会把按钮顶上来,如果上述代码中fixHeight设置不合适,会导致这个按钮遮挡输入框。所以为了统一效果,将底部按钮取消fixed,随页面滚动。

第二,如果点击键盘上的收起键盘按钮,会导致页面top无法恢复,因为没有触发输入框失焦方法,需点击空白处恢复。(目前没找到解决办法)

6.禁止 iOS 识别长串数字为电话

<meta content="telephone=no" name="format-detection" />

后续

1.由于android弹出键盘存在一定延迟,所以可以给top更改添加setTimeout,设置合适的延迟时间。

2.两个h5框架,iScroll、Native.js(虽然在这个问题上没啥用)

3.最终奥义:修改设计稿,三招 -> 使输入框不在页面的下半部分、采用分页设计、弹出输入层(ps:要和产品和设计沟通,客户不一定会让步 0.0)

希望大家斧正,交流更好地解决方案,谢谢

7.禁止 iOS 弹出各种操作窗口

-webkit-touch-callout:none

8.消除 transition 闪屏

-webkit-transform-style: preserve-3d;     /*设置内嵌的元素在 3D 空间如何呈现:保留 3D*/
-webkit-backface-visibility: hidden;      /*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/

9.iOS 系统中文输入法输入英文时,字母之间可能会出现一个六分之一空格

可以通过正则去掉      this.value = this.value.replace(/u2006/g, '');

10.禁止ios和android用户选中文字

-webkit-user-select:none

11.在ios和andriod中,audio元素和video元素在无法自动播放

应对方案:触屏即播

$('html').one('touchstart',function(){
    audio.play()
})

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

<input autocapitalize="off" autocorrect="off" />

13.android下取消输入语音按钮

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

14  CSS动画页面闪白,动画卡顿

俄罗斯贵宾会 4

解决方法:
1.尽可能地使用合成属性transform和opacity来设计CSS3动画,不使用position的left和top来定位
2.开启硬件加速

  -webkit-transform: translate3d(0, 0, 0);
     -moz-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
          transform: translate3d(0, 0, 0);

俄罗斯贵宾会 5

16.fixed定位缺陷

ios下fixed元素容易定位出错,软键盘弹出时,影响fixed元素定位

android下fixed表现要比iOS更好,软键盘弹出时,不会影响fixed元素定位

ios4下不支持position:fixed

解决方案: 可用iScroll插件解决这个问题

17.阻止旋转屏幕时自动调整字体大小

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

18 Input 的placeholder会出现文本位置偏上的情况

input 的placeholder会出现文本位置偏上的情况:PC端设置line-height等于height能够对齐,而移动端仍然是偏上,解决是设置line-height:normal

19 往返缓存问题

点击浏览器的回退,有时候不会自动执行js,特别是在mobilesafari中。这与往返缓存(bfcache)有关系。

解决方法 :window.onunload = function(){};

20. calc的兼容性处理

CSS3中的calc变量在iOS6浏览器中必须加-webkit-前缀,目前的FF浏览器已经无需-moz-前缀。
Android浏览器目前仍然不支持calc,所以要在之前增加一个保守尺寸:

div { 
    width: 95%; 
    width: -webkit-calc(100% - 50px); 
    width: calc(100% - 50px); 
}

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:移动端兼容性问题解决方案

您可能还会对下面的文章感兴趣: