挥别web移动端开发差异和经典坑

2,155 阅读5分钟

web移动端

电话号码识别差异

在 iOS Safari (其他浏览器和 Android 均不会)上会对那些看起来像是电话号码的数字处理为电话链接,比如:

  • 7 位数字,形如:1234567
  • 带括号及加号的数字,形如:(+86)123456789
  • 双连接线的数字,形如:00-00-00111
  • 11 位数字,形如:13800138000

关闭识别

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

开启识别

<a href="tel:123456">123456</a>

输入框内阴影差异

描述:在 iOS 上,输入框默认有内部阴影,无法使用 box-shadow 来清除 解决:

input,
textarea {
    /* 方法1: 去掉边框 */
    border: 0;

    /* 方法2: 边框色透明 */
    border-color: transparent;

    /* 方法3: 重置输入框默认外观 */
    -webkit-appearance: none;
    appearance: none;
}

android系统中元素被点击时产生边框

描述:部分android系统点击一个链接,会出现一个边框或者半透明灰色遮罩, 不同生产商定义出来额效果不一样 解决:

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

iOS滑动不流畅

描述:ios 手机上下滑动页面会产生卡顿,手指离开页面,页面立即停止运动。整体表现就是滑动不流畅,没有滑动惯性。 解决: iOS 5.0 以及之后的版本,滑动有定义有两个值 auto 和 touch,默认值为 auto。

  • 在滚动容器上增加滚动 touch 方法
.wrapper {
  -webkit-overflow-scrolling: touch;
}
  • 设置overflow : 设置外部 overflow 为 hidden,设置内容元素 overflow 为 auto。内部元素超出 body 即产生滚动,超出的部分 body 隐藏。
body {
  overflow-y: hidden;
}
.wrapper {
  overflow-y: auto;
}

MDN定义: -webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效果. auto: 使用普通滚动, 当手指从触摸屏上移开,滚动会立即停止。 touch: 使用具有回弹效果的滚动, 当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。

移动端click屏幕产生200-300 ms的延迟,PC端无

问题描述:移动设备上的web网页是有300ms延迟的,往往会造成按钮点击延迟甚至是点击失效。 解决:

  • fastclick可以解决在手机上点击事件的300ms延迟
  • zepto的touch模块,tap事件也是为了解决在click的延迟问题

iOS上拉边界下拉出现空白,安卓无

描述:手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。安卓无此特性。

在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。

解决:

document.body.addEventListener(
  'touchmove',
  function(e) {
    if (e._isScroller) return
    // 阻止默认事件
    e.preventDefault()
  },
  {
    passive: false
  }
)

IOS日期格式转换NAN问题

描述: iOS系统中JS转换字符串变日期对象的时候,字符串格式必须是/相隔,通常情况是-相隔,在微信小程序IOS环境中同样出现出现此问题

iOS系统对js中的new Date()方法有格式要求

let dt = new Date("2019-07-24 19:57") //错误写法
// dt会返回valid Date

let dt = new Date("2019/07/24 19:57")  //正确写法

解决: 'yyyy-MM-dd'.replace(/-/g, '/') 进行字符串匹配转换

IOS键盘弹起挡住原来的视图

描述:ios就是当唤起键盘后,整个页面会被键盘压缩,也就是说页面的高度变小,并且所有的 fixed 全部变为了 absolute ,而 android 中唤起键盘是覆盖在页面上,不会压缩页面

可以通过监听移动端软键盘弹起 Element.scrollIntoViewIfNeeded(Boolean)方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。

关于Element.scrollIntoView()的MDN链接 关于Element.scrollIntoViewIfNeeded()的MDN链接

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

onkeyUp和onKeydown兼容差异

用 input 监听键盘 keyup、keydown事件,在安卓手机浏览器中没有问题,但是在 ios 手机浏览器中用输入法输入之后,并未立刻相应 keyup、keydown 事件

非直接的文字输入(中文输入法)下,进行判断限制,仅在选词后触发input事件

描述:在使用oninput监控输入框内容变化时,我们期望仅在value值变化时,才触发oninput事件,而在中文输入下,未选词时的按键也会触发oninput事件。

关键解决:composition event

  • compositonstart: 在IME的文本复合系统打开时触发,表示要开始输入例如(输入法出现的那一刻)
  • compositionupdate: 在向输入字段中插入新字符时触发(使用输入法输入的过程中)
  • compositionend: 在输入法编辑器的文本复合系统关闭时触发,表示返回正常键盘输入状态(选中文字,输入法消失的那一刻)

判断限制:

    $('#input').on('compositionend', function(e) {
        var len = $(this).val().length;
        if (len > 16) {
            // 提示超过16字
        }
    });

选词后触发input事件:

var typing = false;
$('#ipt').on('compositionstart',function(){
    typing = true;
})
$('#ipt').on('compositionend',function(){
    typing = false;
})
//oninput在oncompositionend之前执行,需加定时器
$('#ipt').on('input',function(){
    setTimeout(function() {
        if(!typing) {
            //To do something...
        }
    },0);
})

微信小程序

webp格式IOS不支持

描述:在小程序内部,IOS不支持webp格式,安卓支持; 时间:201908

setData设置KB数有误

描述:虽然官方文档说 setData 设置数据的时候不能超过1024KB,小程序在IOS下单次设置的数据不能超过1024kB ,设置会有问题,安卓没问题; 时间:201908

IOS系统微信版本兼容

描述: IOS8系统 只能 兼容最高微信版本 6.72 ,IOS系统9 可以兼容微信版本7.0.0 以上。

wx.onSocket断后再次发送链接IOS和安卓差异

描述:小程序 wx.onSocket 链接 在手动断网后,IOS会不停发送请求再链接onSocketOpen,安卓不会 ,解决方法,做一个定时器启动链接 时间:201908

部分安卓机器点击键盘发送相同内容

描述:部分安卓机,如oppo 快速点击键盘发送,会发出2条一样的内容,防抖与节流均不生效; 时间:201907

微信公众号

安卓在微信授权回调带#的URL跳转会出现空白

描述:安卓手机,在微信授权回调的函数中进行跳转至的URL不能带有#,但#号可放置在结尾。如: www.xuejiehome.com/#/home,跳转至微…

如:www.xuejiehome.com/#/home ,跳转至微信授权后,回调接口再次跳转至http://www.xuejiehome.com/#/home?arg=test,即在地址最后增加一个参数,微信中显示空白。

如:www.xuejiehome.com/#/home 跳转至微信授权后,回调接口再次跳转至http://www.xuejiehome.com/?arg=test#home 即在#home前增加一个参数,页面跳转正常。

经排查,原因如下: 原来是缓存导致的,因其#号后的参数等都被忽略,那么#以前的URL在授权前和授权后一致,其不再发送网页请求去重新获取而是直接读取缓存。

解决方法: 刷新需要跳转到的URL,可使用PHP的Header跳转,默认header是不刷新的。 header("Refresh: 0; url={$go}"); 或者还可以输出js脚本跳转:

echo "<script>window.location.href='{$go}'</script>";

累积中,上文存在错误情况请指正

参考:

总结移动端H5开发常用技巧(干货满满哦!)