webApp开发一些兼容性的坑

移动端input处理

禁用选择复制带来的问题

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

  * {
      -webkit-user-select: none;
      /*webkit浏览器*/
      -khtml-user-select: none;
      /*早期浏览器*/
      -moz-user-select: none;
      /*火狐*/
      -ms-user-select: none;
      /*IE10*/
      user-select: none;
  }

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

  [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;
  }

默认输入框样式处理

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

调用相机,摄像,录音

使用input:file标签, 去调用系统默认相机,摄像,录音功能,capture属性指定功能
    <!-- 照相 -->
    <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。
```html
<input ref="selectImg" type="file" @change="selectImg"accept="image/*" multiple style="display: none;"/>
```
  1. 点击按钮触发input的选择事件
```javascript
   this.$refs.selectImg.dispatchEvent(new MouseEvent('click'))
```
  1. 然后绑定change事件,或者file数据流,进行上传、存储等操作。
```javascript
    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属性,则会失效

<!-- 一般数字 -->
<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. 聊天类的输入框始终在底部,一般都是通过绝对定位固定在底部的,所以前面两种处理方案都不可行。这样也就带来了兼容性的问题
    // 设置输入框始终可见(即软键盘弹出时,如果把输入框遮挡住,输入框会滚到可视区域)
    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点击、或者长按某个区域后有阴影

* {
    /* 关键代码 */
    -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. 利用七牛云的图片样式,对图片进行处理(裁剪、压缩大小、加水印等)。

页面白屏

一个已经上线的项目,客户反映:IOS9.2、IOS9.3的苹果手机打开白屏。

分析原因

当时猜想是不是IOS9的系统浏览器版本太低,不支持一些语法导致的。

启动IOS9的模拟器,再连接浏览器,查看console的错误日志。果然,有一个错误就是不能识别const,再查看详细内容,是引用的Swiper中的一个swiper.bundle.js导致的。然后再查看Swiper的引用,部分代码还是es6语法。

处理方案

下载离线Swiper,然后在index.html中静态引用。

如果有的组件没有离线版本,可复制源码,然后放在src/目录文件夹下的任何地方,那么打包的时候就会编译成兼容性好的es5语法(前提是引用的babel)

display: grid语法不支持

这个可以用其他的一些写法实现。

  1. 使用table
  2. 使用float

比较麻烦的是怎么实现grid布局中的gap?box-sizing: border-box可以实现这一功能。

box-sizing 属性值说明:

  1. content-box默认值,标准盒子模型。 width 与 height 只包括内容的宽和高, 不包括边框(border),内边距(padding),外边距(margin)。注意: 内边距, 边框 & 外边距 都在这个盒子的外部。 比如. 如果 .box {width: 350px}; 而且 {border: 10px solid black;} 那么在浏览器中的渲染的实际宽度将是370px;

尺寸计算公式:width = 内容的宽度,height = 内容的高度。宽度和高度都不包含内容的边框(border)和内边距(padding)。

  1. border-boxwidth 和 height 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks模式 时Internet Explorer使用的盒模型。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 导致在浏览器中呈现的宽度为350px的盒子。内容框不能为负,并且被分配到0,使得不可能使用border-box使元素消失。

这里的维度计算为:

width = border + padding + 内容的 width,

height = border + padding + 内容的 height。

  1. padding-boxwidth 和 height 属性包括内容和内边距,但是不包括边框和外边距。只有Firefox实现了这个值,它在Firefox 50中被删除。

实现

参考element-ui中的Row、Col组件。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值