原文鏈接 (https://www.toutiao.com/i6751364844672254478/)
最近給公司微信公衆號,寫了微信h5業務頁面,總結分享一下前端開發過程中的幾個兼容性坑,項目直接拿的公司頁面,所以下文涉及圖片都模糊處理了。
一、ios端兼容input光標高度
問題詳情描述:input輸入框光標,在安卓手機上顯示沒有問題,但是在蘋果手機上
當點擊輸入的時候,光標的高度和父盒子的高度一樣。例如下圖,左圖是正常所期待的輸入框光標,右邊是ios的input光標。
微信 H5 頁面兼容性,看看大神的解決方案
出現原因分析:通常我們習慣用height屬性設置行間的高度和line-height屬性設置行間的距離(行高),當點擊輸入的時候,光標的高度就自動和父盒子的高度一樣了。(谷歌瀏覽器的設計原則,還有一種可能就是當沒有內容的時候光標的高度等於input的line-height的值,當有內容時,光標從input的頂端到文字的底部
解決辦法:高度height和行高line-height內容用padding撐開
例如:
.content{
float: left;
box-sizing: border-box;
height: 88px;
width: calc(100% - 240px);
.content-input{
display: block;
box-sizing: border-box;
width: 100%;
color: #333333;
font-size: 28px;
//line-height: 88px;
padding-top: 20px;
padding-bottom: 20px;
}
}
二、ios端微信h5頁面上下滑動時卡頓、頁面缺失
問題詳情描述:在ios端,上下滑動頁面時,如果頁面高度超出了一屏,就會出現明顯的卡頓,頁面有部分內容顯示不全的情況,例如下圖,右圖是正常頁面,邊是ios上下滑動後,卡頓導致如左圖下面部分丟失。
微信 H5 頁面兼容性,看看大神的解決方案
出現原因分析:
籠統說微信瀏覽器的內核,Android上面是使用自帶的WebKit內核,iOS裏面由於蘋果的原因,使用了自帶的Safari內核,Safari對於overflow-scrolling用了原生控件來實現。對於有-webkit-overflow-scrolling的網頁,會創建一個UIScrollView,提供子layer給渲染模塊使用。【有待考證】
解決辦法:只需要在公共樣式加入下面這行代碼
*{
-webkit-overflow-scrolling: touch;
}
But,這個屬性是有bug的,比如如果你的頁面中有設置了絕對定位的節點,那麼該節點的顯示會錯亂,當然還有會有其他的一些bug。
拓展知識: -webkit-overflow-scrolling:touch是什麼?
MDN上是這樣定義的:
-webkit-overflow-scrolling 屬性控制元素在移動設備上是否使用滾動回彈效果.auto: 使用普通滾動, 當手指從觸摸屏上移開,滾動會立即停止。touch: 使用具有回彈效果的滾動, 當手指從觸摸屏上移開,內容會繼續保持一段時間的滾動效果。繼續滾動的速度和持續的時間和滾動手勢的強烈程度成正比。同時也會創建一個新的堆棧上下文。
三、ios鍵盤喚起,鍵盤收起以後頁面不歸位
問題詳情描述:
輸入內容,軟鍵盤彈出,頁面內容整體上移,但是鍵盤收起,頁面內容不下滑
出現原因分析:
固定定位的元素 在元素內 input 框聚焦的時候 彈出的軟鍵盤佔位 失去焦點的時候軟鍵盤消失 但是還是佔位的 導致input框不能再次輸入 在失去焦點的時候給一個事件
解決辦法:
changeBlur(){
let u = navigator.userAgent, app = navigator.appVersion;
let isIOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/);
if(isIOS){
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
window.scrollTo(0, Math.max(scrollHeight - 1, 0))
}, 200)
}
}
拓展知識: position: fixed的元素在ios裏,收起鍵盤的時候會被頂上去,特別是第三方鍵盤
四、安卓彈出的鍵盤遮蓋文本框
問題詳情描述:
安卓微信H5彈出軟鍵盤後擋住input輸入框,如下左圖是期待喚起鍵盤的時候樣子,右邊是實際喚起鍵盤的樣子
微信 H5 頁面兼容性,看看大神的解決方案
出現原因分析:待補充
解決辦法:給input和textarea標籤添加focus事件,如下,先判斷是不是安卓手機下的操作,當然,可以不用判斷機型,Document 對象屬性和方法,setTimeout延時0.5秒,因爲調用安卓鍵盤有一點遲鈍,導致如果不延時處理的話,滾動就失效了
changefocus(){
let u = navigator.userAgent, app = navigator.appVersion;
let isAndroid = u.indexOf(‘Android’) > -1 || u.indexOf(‘Linux’) > -1;
if(isAndroid){
setTimeout(function() {
document.activeElement.scrollIntoViewIfNeeded();
document.activeElement.scrollIntoView();
}, 500);
}
}
拓展知識:
Element.scrollIntoView()方法讓當前的元素滾動到瀏覽器窗口的可視區域內。而Element.scrollIntoViewIfNeeded()方法也是用來將不在瀏覽器窗口的可見區域內的元素滾動到瀏覽器窗口的可見區域。但如果該元素已經在瀏覽器窗口的可見區域內,則不會發生滾動
五、安卓彈出的鍵盤遮蓋文本框另外一種解決方案
// AndroidBugWorkaround.java
/**
* 正確解決webview不能adjustResize的處理類(包含了沉浸式狀態欄以及虛擬按鍵等情況的適配設置)
*/
public class AndroidBugWorkaround {
public static void assistActivity(Activity activity) {
new AndroidBugWorkaround(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private Activity activity;
private int statusBarHeight;
private AndroidBugWorkaround(Activity activity) {
//獲取狀態欄的高度
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
this.activity = activity;
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
mChildOfContent = content.getChildAt(0);
//界面出現變動都會調用這個監聽事件
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
frameLayoutParams = (FrameLayout.LayoutParams)
mChildOfContent.getLayoutParams();
}
private boolean mIsFirstResize = true;
private int mChildOfContentSize = 0;
private int usableHeightNow;
private void possiblyResizeChildOfContent() {
//錯誤做法拿到usableHeightNow
// int usableHeightNow = computeUsableHeight();
if (mIsFirstResize) {
//保留原來系統默認算好的mChildOfContent高度(根據flag和系統狀態欄和下面虛擬按鍵和諧相處的正確值)
mChildOfContentSize = mChildOfContent.getHeight();
mIsFirstResize = false;
}
usableHeightNow = mChildOfContent.getHeight();
if (usableHeightNow != usableHeightPrevious) {
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
if (heightDifference > (usableHeightSansKeyboard / 4)) {
// keyboard probably just became visible
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
} else {
// keyboard probably just became hidden
//這裏不能單純使用frameLayoutParams.height = computeUsableHeight(); 因爲usableHeightNow和一些flag有關,網上frameLayoutParams.height = usableHeightSansKeyboard 直接就錯了,因爲usableHeightSansKeyboard恆爲全屏高度
//1.當使用 window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN) 全屏時getWindowVisibleDisplayFrame高度爲全屏(系統狀態欄和下面虛擬按鍵呼出懸浮在上面)
//2.當使用FLAG_TRANSLUCENT_STATUS 的時候getWindowVisibleDisplayFrame拿到的是不包含系統狀態欄的高度但是又頂上了系統欄的位置,導致出錯
//綜合上述幾點正確做法爲當前代碼實現,即使用系統默認算好的mChildOfContent高度,當鍵盤喚起,保留當前mChildOfContent高度,鍵盤消失再設置回去
frameLayoutParams.height = mChildOfContentSize;
}
mChildOfContent.requestLayout();
usableHeightPrevious = frameLayoutParams.height;
}
}
/**
* 計算mChildOfContent可見高度 ** @return
*/
/* private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return (r.bottom - r.top);
}
*/
}
- 2、在webview宿主activity中加入
AndroidBugWorkaround.assistActivity(this);//解決webview頁面鍵盤不能頂起佈局
六、Vue中路由使用hash模式,開發微信H5頁面分享時在安卓上設置分享成功,但是ios的分享異常
問題詳情描述:
ios當前頁面分享給好友,點擊進來是正常,如果二次分享,則跳轉到首頁;使用vue router跳轉到第二個頁面後在分享時,分享設置失敗;以上安卓分享都是正常
微信 H5 頁面兼容性,看看大神的解決方案
出現原因分析:jssdk是後端進行簽署,前端校驗,但是有時跨域,ios是分享以後會自動帶上 from=singlemessage&isappinstalled=0 以及其他參數,分享朋友圈參數還不一樣,貌似系統不一樣參數也不一樣,但是每次獲取url並不能獲取後面這些參數
解決辦法:
(1)可以使用改頁面this.$router.push跳轉,爲window.location.href去跳轉,而不使用路由跳轉,這樣可以使地址欄的地址與當前頁的地址一樣,可以分享成功(適合分享的頁面不多的情況下,作爲一個單單頁運用,這樣刷新頁面跳轉,還是…)
(2)把入口地址保存在本地,等需要獲取簽名的時候 取出來,注意:sessionStorage.setItem(‘href’,href); 只在剛進入單應用的時候保存!【該方法未驗證】
題外話:
如果能用小程序寫的頁面,儘量上小程序吧,H5開發在微信開發者工具裏看頁面效果可能看不出問題,因爲不能喚起軟鍵盤。避免頻繁線上發佈,可以用花生殼或者idcfengye,做內網穿透,搭建一個可以通過域名訪問的開發環境的h5頁面,在手機上看看效果,對了微信內置瀏覽器緩存機制。會導致剛提交的代碼(特別是js)效果要半個小時左右才生效。
最後:
微信H5頁面其實很多知識,登陸授權,jssdk授權,這裏就只做了分享,當然還有上傳圖片、微信支付等功能,都可能會遇到坑,以上幾個坑也是比較常遇到的,如果有更好的解決方案的話,歡迎在留言區分享