移动端H5开发踩坑记录

html 篇

常用的meta属性设置

  • 屏幕设置
<meta name="screen-orientation" content="portrait"> //Android 禁止屏幕旋转
<meta name="full-screen" content="yes">             //全屏显示
<meta name="browsermode" content="application">     //UC应用模式,使用了application这种应用模式后,页面讲默认全屏,禁止长按菜单,禁止收拾,标准排版,以及强制图片显示。
<meta name="x5-orientation" content="portrait">     //QQ强制竖屏
<meta name="x5-fullscreen" content="true">          //QQ强制全屏
<meta name="x5-page-mode" content="app">            //QQ应用模式

  • 电话号码识别

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

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

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


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

  • 邮箱识别(Android)

安卓上会对符合邮箱格式的字符串进行识别,我们可以通过如下的 meta 来管别邮箱的自动识别


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


<a mailto:[email protected]">[email protected]a>

css 篇

  • 0.5px细线

DPR(devicePixelRatio) 设备像素比,它是默认缩放为 100%的情况下,设备像素和 CSS 像素的比值。目前主流的屏幕 DPR=2(iPhone 8),或者 3(iPhone 8 Plus)。拿 2 倍屏来说,设备的物理像素要实现 1 像素,而 DPR=2,所以 css 像素只能是 0.5

/* 底边框 */ 
.b-border { 
  position: relative; 
} 
.b-border:before { 
  content: ''; 
  position: absolute; 
  left: 0; 
  bottom: 0; 
  width: 100%; 
  height: 1px; 
  background: #d9d9d9; 
  -webkit-transform: scaleY(0.5); 
  transform: scaleY(0.5); 
  -webkit-transform-origin: 0 0; 
  transform-origin: 0 0; 
} 
/* 上边框 */ 
.t-border { 
  position: relative; 
} 
.t-border:before { 
  content: ''; 
  position: absolute; 
  left: 0; 
  top: 0; 
  width: 100%; 
  height: 1px; 
  background: #d9d9d9; 
  -webkit-transform: scaleY(0.5); 
  transform: scaleY(0.5); 
  -webkit-transform-origin: 0 0; 
  transform-origin: 0 0; 
} 
/* 右边框 */ 
.r-border { 
  position: relative; 
} 
.r-border:before { 
  content: ''; 
  position: absolute; 
  right: 0; 
  bottom: 0; 
  width: 1px; 
  height: 100%; 
  background: #d9d9d9; 
  -webkit-transform: scaleX(0.5); 
  transform: scaleX(0.5); 
  -webkit-transform-origin: 0 0; 
  transform-origin: 0 0; 
} 
/* 左边框 */ 
.l-border { 
  position: relative; 
} 
.l-border:before { 
  content: ''; 
  position: absolute; 
  left: 0; 
  bottom: 0; 
  width: 1px; 
  height: 100%; 
  background: #d9d9d9; 
  -webkit-transform: scaleX(0.5); 
  transform: scaleX(0.5); 
  -webkit-transform-origin: 0 0; 
  transform-origin: 0 0; 
} 
 
/* 四条边 */ 
.setBorderAll { 
  position: relative; 
  &:after { 
    content: ' '; 
    position: absolute; 
    top: 0; 
    left: 0; 
    width: 200%; 
    height: 200%; 
    transform: scale(0.5); 
    transform-origin: left top; 
    box-sizing: border-box; 
    border: 1px solid #e5e5e5; 
    border-radius: 4px; 
  } 
} 
  • 屏蔽用户选择
div {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

  • 清除IOS输入框内阴影
div {
  -webkit-appearance: none;
}

  • 禁止保存或拷贝图像
img {
  -webkit-touch-callout: none;
}

  • 设置 输入框 里面 placeholder 字体的颜色
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder {
  color: #c7c7c7;
}
input:-moz-placeholder,
textarea:-moz-placeholder {
  color: #c7c7c7;
}
input:-ms-input-placeholder,
textarea:-ms-input-placeholder {
  color: #c7c7c7;
}

  • 字体禁止缩放

用户设置字号放大或者缩小导致页面布局错误

body {
  -webkit-text-size-adjust: 100% !important;
  text-size-adjust: 100% !important;
  -moz-text-size-adjust: 100% !important;
}

  • 去除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。

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

js 篇

  • 移动端click屏幕产生200-300 ms的延迟响应

移动设备上的web网页是有300ms延迟的,往往会造成按钮点击延迟甚至是点击失效

  1. fastclick可以解决在手机上点击事件的300ms延迟
  2. zepto的touch模块,tap事件也是为了解决在click的延迟问题
    触摸事件的响应顺序:ontouchstart、ontouchmove、ontouchend、onclick

  • audio 和 video 在 ios 和 andriod 中自动播放

苹果系统和安卓系统通常都会禁止自动播放和使用 JS 的触发播放,必须由用户来触发才可以播放。加入自动触发播放的代码

  1. audio元素的autoplay属性在IOS及Android上无法使用,在PC端正常;
  2. audio元素没有设置controls时,在IOS及Android会占据空间大小,而在PC端Chrome是不会占据任何空间;
  3. 注意不要遗漏微信的兼容处理需要引用微信JS
<audio controls="controls"> 
        <source src="music/bg.ogg" type="audio/ogg">source>
        <source src="music/bg.mp3" type="audio/mpeg">source>
        //优先播放音乐bg.ogg,不支持再播放bg.mp3
audio>
$('html').one('touchstart', function() { 
  audio.play() 
}) 

//微信端兼容处理
document.addEventListener("WeixinJSBridgeReady", function () {
    music.play();
}, false);

  • iOS 上拉边界下拉出现空白

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

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

  • ios 日期转换 NAN 的问题

将日期字符串的格式符号替换成’/’

'yyyy-MM-dd'.replace(/-/g, '/') 

  • 软键盘问题

IOS 键盘弹起挡住原来的视图,可以通过监听移动端软键盘弹起

  • Element.scrollIntoViewIfNeeded(Boolean)方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。
    • true,则元素将在其所在滚动区的可视区域中居中对齐。
    • false,则元素将与其所在滚动区的可视区域最近的边缘对齐。 根据可见区域最靠近元素的哪个边缘,元素的顶部将与可见区域的顶部边缘对准,或者元素的底部边缘将与可见区域的底部边缘对准。
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 兼容性问题

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


  • IOS12 输入框难以点击获取焦点,弹不出软键盘

定位找到问题是 fastclick.js 对 IOS12 的兼容性,可在 fastclick.js 源码或者 main.js 做以下修改

FastClick.prototype.focus = function(targetElement) {
  var length
  if (
    deviceIsIOS &&
    targetElement.setSelectionRange &&
    targetElement.type.indexOf('date') !== 0 &&
    targetElement.type !== 'time' &&
    targetElement.type !== 'month'
  ) {
    length = targetElement.value.length
    targetElement.setSelectionRange(length, length)
    targetElement.focus()
  } else {
    targetElement.focus()
  }
}


  • IOS 键盘收起时页面没用回落,底部会留白

通过监听键盘回落时间滚动到原来的位置

window.addEventListener('focusout', function() {
  window.scrollTo(0, 0)
})

//input输入框弹起软键盘的解决方案。
var bfscrolltop = document.body.scrollTop
$('input')
  .focus(function() {
    document.body.scrollTop = document.body.scrollHeight
    //console.log(document.body.scrollTop);
  })
  .blur(function() {
    document.body.scrollTop = bfscrolltop
    //console.log(document.body.scrollTop);
  })


  • IOS 下 fixed 失效的原因

软键盘唤起后,页面的 fixed 元素将失效,变成了 absolute,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。不仅限于 type=text 的输入框,凡是软键盘(比如时间日期选择、select 选择等等)被唤起,都会遇到同样地问题。

解决方法: 不让页面滚动,而是让主体部分自己滚动,主体部分高度设为 100%,overflow:scroll

<body>
  <div class='warper'>
    <div class='main'>div>
  <div>
  <div class="fix-bottom">div>
body>

.warper {
  position: absolute;
  width: 100%;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch; /* 解决ios滑动不流畅问题 */
}
.fix-bottom {
  position: fixed;
  bottom: 0;
  width: 100%;
}

作者:lzg9527
链接:https://juejin.im/post/5e4a0162f265da57133b2005
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(项目开发)