app端 h5 頁面兼容性問題和解決方案

一、ios端兼容input光標高度

問題詳情描述:input輸入框光標,在安卓手機上顯示沒有問題,但是在蘋果手機上
當點擊輸入的時候,光標的高度和父盒子的高度一樣, ios手機上顯得很醜
解決辦法:高度height和行高line-height內容用padding撐開

二、ios端微信h5頁面上下滑動時卡頓、頁面缺失

問題詳情描述:在ios端,上下滑動頁面時,如果頁面高度超出了一屏,就會出現明顯的卡頓,頁面有部分內容顯示不全的情況,例如下圖,右圖是正常頁面,邊是ios上下滑動後,卡頓導致如左圖下面部分丟失。

微信 H5 頁面兼容性,看看大神的解決方案

出現原因分析:

籠統說微信瀏覽器的內核,Android上面是使用自帶的WebKit內核,iOS裏面由於蘋果的原因,使用了自帶的Safari內核,Safari對於overflow-scrolling用了原生控件來實現。對於有-webkit-overflow-scrolling的網頁,會創建一個UIScrollView,提供子layer給渲染模塊使用。【有待考證】

解決辦法:只需要在公共樣式加入下面這行代碼

*{
	 -webkit-overflow-scrolling: touch;
}
三、ios鍵盤喚起,鍵盤收起以後頁面不歸位

問題詳情描述:

輸入內容,軟鍵盤彈出,頁面內容整體上移,但是鍵盤收起,頁面內容不下滑

出現原因分析:

固定定位的元素 在元素內 input 框聚焦的時候 彈出的軟鍵盤佔位 失去焦點的時候軟鍵盤消失 但是還是佔位的 導致input框不能再次輸入 在失去焦點的時候給一個事件

解決辦法:

<div class="list-warp">
 <div class="title"><span>投·被保險人姓名</span></div>
 <div class="content">
 <input class="content-input"
 placeholder="請輸入姓名"
 v-model="peopleList.name"
 @focus="changefocus()"
 @blur.prevent="changeBlur()"/> 
 </div>
 </div>

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輸入框,如下左圖是期待喚起鍵盤的時候樣子,右邊是實際喚起鍵盤的樣子

解決辦法:給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頁面鍵盤不能頂起佈局
六、h5禁止頁面放大縮小

android端只需要在index.html中設置如下
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover"">
ios端

window.onload = function () {

    document.addEventListener('gesturestart', function (e) {
        e.preventDefault();
    });
    document.addEventListener('dblclick', function (e) {
        e.preventDefault();
    });

    // 阻止雙擊放大
    var lastTouchEnd = 0;
    document.addEventListener('touchstart', function (event) {
        if (event.touches.length > 1) {
            event.preventDefault();
        }
    });
    document.addEventListener('touchend', function (event) {
        var now = (new Date()).getTime();
        if (now - lastTouchEnd <= 300) {
            event.preventDefault();
        }
        lastTouchEnd = now;
    }, false);

    // 阻止雙指放大
    document.addEventListener('gesturestart', function (event) {
        event.preventDefault();
    });

    var roll = document.body.scrollTop;
}
七、頁面rem適配
(function () {
    function setPxPerRem() { // 把viewport分成10份的rem,html標籤的font-size設置爲1rem的大小;
        var pxPerRem = document.getElementsByTagName("html")[0].offsetWidth / 10;
        document.getElementsByTagName("html")[0].setAttribute("style", "font-size:" + pxPerRem + "px !important");
    }

    setPxPerRem();
})();
八、url鏈接參數的值
function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var url = decodeURI(window.location.search);
    var r = url.substr(1).match(reg);
    if (r != null) return unescape(r[2]);
    return null;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章