webApp开发一些兼容性的坑

通过做嗨黔东南APP(IOS,Android)这个项目遇到过很多兼容性的坑,写博客记录备份一下,以免再次踩坑。

移动端input处理

禁用选择复制带来的问题

大多数在禁用选择复制的问题都是通过user-select: none来处理。代码如下:

1
2
3
4
5
6
7
8
9
10
11
* {
-webkit-user-select: none;
/*webkit浏览器*/
-khtml-user-select: none;
/*早期浏览器*/
-moz-user-select: none;
/*火狐*/
-ms-user-select: none;
/*IE10*/
user-select: none;
}

注意,这个是用*禁止所有的元素的选择复制属性,在IOS中会导致inpput、textarea无法获取焦点,应该特别处理

1
2
3
4
5
6
7
8
[contenteditable="true"], input, textarea {
-webkit-user-select: auto !important;
-khtml-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
-o-user-select: auto !important;
user-select: auto !important;
}

默认输入框样式处理

1
2
3
4
5
6
7
8
9
/* 去除内部阴影 */
input, textarea {
border: 0; /* 方法1 */
-webkit-appearance: none; /* 方法2 */
}
/* 去掉选中时默认的边框 */
input:focus {
outline: none
}

调用相机,摄像,录音

使用input:file标签, 去调用系统默认相机,摄像,录音功能,capture属性指定功能
1
2
3
4
5
6
7
<!-- 照相 -->
<input type="file" accept="image/*" capture="camera">
<!-- 摄像 -->
<input type="file" accept="video/*" capture="camcorder">
<!-- 录音 -->
<input type="file" accept="audio/*" capture="microphone">
<!-- 可以添加multiple属性支持多选,但是capture会失效 -->
**上传图片案例**
1. 隐藏input。

1
<input ref="selectImg" type="file" @change="selectImg"accept="image/*" multiple style="display: none;"/>
2. 点击按钮触发input的选择事件
1
this.$refs.selectImg.dispatchEvent(new MouseEvent('click'))
3. 然后绑定change事件,或者file数据流,进行上传、存储等操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
selectImg (e) {
if (e.target.files.length > 0 && e.target.files[0].size === 0) return
if (e.target.files.length > 15) {
this.$vux.toast.text('最多只能选15张图片', 'middle')
return
}
const _self = this
uploadFile(this, e.target.files, (data) => {
let temp = []
data.forEach(item => {
temp.push(item.downloadPath)
})
e.target.value = ''
_self.setSelectPic(temp)
}, null, false)
_self.$router.push('/meiTu/publishDynamic')
}
}

数字键盘

一般情况,在input的标签里面type设置为number机可以打开数字键盘。如果有长度限制添加maxlength属性,则会失效

1
2
3
4
<!-- 一般数字 -->
<input type="number" maxlength="6" pattern="[0-9]*" oninput="if(value.length>6)value=value.slice(0,6)"/>
<!-- 电话号码 -->
<input type="tel" maxlength="11">

软键盘弹起,输入框位置的问题

常见的处理方案:

  1. 把输入框放在页面顶部,软键盘的高度不会超过页面的高度的一半,这样可避免软键盘弹起对输入框造成的影响。例如顶部搜索框。
  2. 弹出一个新的页面/窗体来放置输入框。例如:评论、最近搜索
  3. 聊天类的输入框始终在底部,一般都是通过绝对定位固定在底部的,所以前面两种处理方案都不可行。这样也就带来了兼容性的问题

    1
    2
    3
    // 设置输入框始终可见(即软键盘弹出时,如果把输入框遮挡住,输入框会滚到可视区域)
    inputElement.scrollIntoView()
    inputElement.scrollIntoViewIfNeeded()

    可能会出现的问题:
    1.1 如果Android的Activity中设置android: windowSoftInputMode = “adjustPan”,窗口不会调用onSizeChanged方法,界面的一部分就会被软键盘覆盖住。
    1.2 IOS中整体页面会被网上顶上去,用户体验不友好。

    针对上面的问题的处理方案(需要Native提供js接口支持):
    第一步, 监听软键盘的打开、关闭状态,并计算出软键盘的高度。(这一步需要Native来做)
    第二步, (Android)根据软件的高度变化,来控制输入框的位置。比如:绝对定位的话控制该输入框的bottom属性。非绝对定位则在输入框下面添加等同于键盘高度的div就可以了
    第三步, (IOS) IOS中由于软键盘弹起会导致整个页面向上滚动,需要把向上滚动区域的元素重新定位。

IOS中一些莫名其妙的坑

margin-bottom无效

移步另外一篇文章。IOS中margin-bottom无效

transform时z-index无效,以及影响position:fixed

原因: Safari中3D变换会忽略z-index的层级

在Safari浏览器下,此Safari浏览器包括iOS的Safari,iPhone上的微信浏览器,以及Mac OS X系统的Safari浏览器,当我们使用3D transform变换的时候,如果祖先元素没有overflow:hidden/scroll/auto等限制,则会直接忽略自身和其他元素的z-index层叠顺序设置,而直接使用真实世界的3D视角进行渲染。

处理方案

  1. 父级,任意父级,非body级别,设置overflow:hidden可恢复和其他浏览器一样的渲染。
  2. 以毒攻毒。页面比较复杂,不方便设置overflow的时候,可设置一个足够大的translateZ值。

IOS点击、或者长按某个区域后有阴影

1
2
3
4
* {
/* 关键代码 */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); /* 或者transparent */
}

一些应该注意的地方。

  1. iPhone X, 在Vue做开发中,在APP.vue的created中获取window.innerHeight竟然不等于屏幕显示高度,页面重新layout过后竟然又可以了。我没有找到原因。处理方案是 用document.body.offsetHeight代替(前提是body的高度为100%或者100vh)。
  2. 一般的Android手机、IOS手机的StatusBar的高度为24px,iPhone X中的statusBar的高度为44px,底部的空余的高度为34px。
    IPhone X屏幕分配

一些兼容的优化处理

字体大小、宽高比例适配

  1. 字体:移动端一般默认字体是16px/14px,然后其他字体大小按照比例用rem来做调整。
  2. 宽高:尽量使用vw, vh单位来做适配。从设计稿中直接拿出宽高的像素值或者做比例缩放,往往只能适配常用的部分手机,在一些手机中的实际效果和设计稿有一些差别。
  3. 总结,移动设备的多样化,屏幕大小的个性化,做适配也就成了最麻烦的事,特别是iPhone X的刘海设计、18:9的屏占比。因此,用比例值的单位来做适配变得尤为重要。把一些常用的大小、颜色、边距、样式代码块等做成可配置的(Stylus、Sass、Less都支持这样的语法),这样会方便很多。

图片适配

  1. img, backgroundImage的灵活使用。img用于加载本地图片、图标比较适合,但是加载网络图片失败时就有点尴尬了。backgroundImage比较方便调整图片显示的方式、位置,加载网络图片时,处理为空、加载中时也比较方便灵活。
  2. 利用七牛云的图片样式,对图片进行处理(裁剪、压缩大小、加水印等)。
坚持原创技术分享,您的支持将鼓励我继续创作!