本文概述了一个项目在收尾阶段遇到的前端兼容性问题及解决方案。主要问题包括:一、在IOS设备上页面滑动和点击事件反应卡顿,通过添加`-webkit-overflow-scrolling: touch;`样式解决滑动不流畅问题,但引起fixed元素不固定等新问题,通过调整布局和替换v-if为v-show解决;并安装fastclick库优化点击事件,但带来input需连续点击的副作用,通过重写fastclick的focus方法解决。二、部分安卓设备点击``无反应,通过重写`openFileChooser`和`onShowFileChooser`方法兼容不同版本安卓的WebView,并在`onActivityResult`中处理返回的图片数据。三、使用mint-UI的`
项目快要告一段落,遇到了很多问题,特别是前端兼容性问题,总结了遇到的这几个坑,以此写下做为收藏。
一. 在IOS设备上页面滑动和点击事件反应比较卡顿
1. 滑动页面卡顿解决方案
//页面布局<template> <div class='content'> 页面内容 </div> </template>
在对应的组件的最外层div上加上这样的样式:
.content{ -webkit-overflow-scrolling: touch; }
-webkit-overflow-scrolling: touch;这句代码最好可在公共的样式中添加,防止很多页面都需要写的麻烦。这句代码虽然可以解决滑动不流畅的问题,但是可能会引起几个小问题:
(1).在滑动界面之中使用的position:fixed 无法固定下来,会随着界面进行一起滚动
解决方法:将使用的position:fixed(头部导航)写在滑动部位外部,在使用绝对定位进行布局,以此解决问题
(2).vue中使用v-if导致的界面第一次无法滑动
解决方法:将v-if改成v-show进行展示,解决界面进入之后不能滑动的问题
2. 点击事件响应缓慢解决方案
(1).安装fastclick (npm install fastclick -S)
(2).在main.js中设置方法
import FastClick from 'fastclick' FastClick.attach(document.body);
在引入fastclick之后,虽然页面事件快了很多,但是会有一个副作用:input输入框需要连续点击两次或者长按才能获取焦点,真是到处是坑啊!
解决方法:在main.js中添加下面的代码
FastClick.prototype.focus = function(targetElement) { var length; // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. if (deviceIsIOS&& targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') { length = targetElement.value.length; targetElement.focus(); targetElement.setSelectionRange(length, length); } else { targetElement.focus(); } };
二. <input type="file">上传图片在部分安卓点击没反应
WebView加载包含上传文件的表单按钮,HTML定义了input标签,同时input的type类型为file,手指点击该按钮,回调openFileChooser这个方法(5.0及以上系统回调onShowFileChooser),然后打开文件选择器选择照片或者文件。
(1). 重写openFileChooser和onShowFileChooser方法,兼容各版本
webview.setWebChromeClient(new WebChromeClient() {
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
this.openFileChooser(uploadMsg, "*/*");
}
// For Android >= 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType) {
this.openFileChooser(uploadMsg, acceptType, null);
}
// For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType, String capture) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
// For Lollipop 5.0+ Devices
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean onShowFileChooser(WebView mWebView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if (mUploadMessage5 != null) {
mUploadMessage5.onReceiveValue(null);
mUploadMessage5 = null;
}
mUploadMessage5 = filePathCallback;
Intent intent = fileChooserParams.createIntent();
try {
startActivityForResult(intent,
FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
} catch (ActivityNotFoundException e) {
mUploadMessage5 = null;
return false;
}
return true;
}
});
(2). 在onActivityResult()中将选择的图片内容通过ValueCallback的onReceiveValue方法返回给WebView,后续通过js上传
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage) {
return;
}
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
} else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
if (null == mUploadMessage5) {
return;
}
mUploadMessage5.onReceiveValue(WebChromeClient.FileChooserParams
.parseResult(resultCode, intent));
mUploadMessage5 = null;
}
}
三.mint-UI 上拉加载下拉刷新
<mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" maxDistance="50px" bottomDistance="20" :bottomDropText="showText" ref="loadmore" :autoFill="isAutoFill" topPullText="加载中..." topDropText="加载中..." > </mt-loadmore>
具体使用方法
//加载数据 loadFristData (currentPage) { var _this = this this.$postHttp(this.$shopUrl + 'api/product/list', {page: currentPage, pageSize: pageSize}) .then((response) => { if (_this.results.length > 0) { for (var i = 0; i < response.result.length; i++) { _this.results.push(response.result[i]) } } else { _this.results = response.result } if (response.result.length < pageSize) { this.showText = '没有更多数据了!' // this.allLoadData = true } }) }, loadTop () { // 下拉刷新 this.allLoaded = false this.showText = '加载更多' var length = this.results.length this.results.splice(0, length) this.courrentPage = 1 this.loadFristData(this.courrentPage) this.$refs.loadmore.onTopLoaded() }, loadBottom () { // 加载更多数据 if (!this.allLoadData) { this.courrentPage = this.courrentPage + 1 this.loadFristData(this.courrentPage) } this.$refs.loadmore.onBottomLoaded() }
问题出现了,当使用fastclick后,每次滑动时都容易触发导点击事件,想着在滑动时阻止冒泡的方式解决
解决方案:
(1).在/node_modules\mint-ui\lib\loadmore\index.js和mint-ui.common.js中handleTouchEnd: function handleTouchEnd(event) {...}中添加如下红色代码:
if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate > 0) {
event.preventDefault();
event.stopPropagation();
if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
event.preventDefault();
event.stopPropagation();
四. 剩余天数,日期,倒计时时在苹果手机上出现NaN
后台返回的是日期字符串。例如:"2018-12-4 10:25:03" 这样的日期,因为苹果的日期格式必须是必须用'/'的格式:2018/12/4 10:25:03这样的格式需要格式化一下就OK。
var newStartDate = new Date('2018-12-4 10:25:03'); newStartDate = newStartDate.replace(/-/g,'/');
文章独发金蝶云社区
推荐阅读