本文是zawa同事寫的一篇博文,相信很多在webapp開發中的同學使用iscroll4會遇到的該問題,問過zawa兄的建議,在這里分享給大家,希望能幫助到各位~
原文地址:http://www.zawaliang.com/2013/10/443.html
問題:在使用了iScroll4的容器內,當表單元素focus聚焦后鍵盤出現時,可能會存在iScroll區域高度不更新,滾動異常問題;而且當前聚焦的表單元素可能不出現在可視區域內,影響用戶體驗。
iKeyboardScroll4就是這么一個解決方案
Github見:https://github.com/zawaliang/iKeyboardScroll4
如今大多數機型都支持onorientationchange事件,iScroll4在不支持onorientationchange事件的機型中使用onresize事件來對滾動區域進行自動刷新操作。所以上面說的表單情況,在大多數機型里都會存在高度不刷新的情況。
RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
那么現在的問題就是檢測鍵盤出現與否,然后調用refresh接口刷新滾動區域高度。由於沒有相應的接口來檢測鍵盤狀態,所以我們通過onresize來檢測窗口高度變化,配合當前元素的聚焦狀態來模擬鍵盤狀態。同時需要考慮在鍵盤出現時翻屏的情況。
由於不確定orientationchange與onresize哪個先觸發,而且Android下orientationchange之后獲取高度存在時間差,所以這里統一到onresize進行處理。
$(window).on('orientationchange', function(e) {
_landscape2 = !!(window.orientation & 2);
}).on('resize', function(e) {
// 不確定orientationchange與onresize哪個先觸發,這里稍微延時
setTimeout(function() {
// Android下orientationchange之后獲取window值會延時
if (_landscape != _landscape2) {
// 屏幕翻轉且翻轉前鍵盤處於顯示狀態時,交換寬高
if (_display) {
var tmpWidth = _initWinWidth;
_initWinWidth = _initWinHeight;
_initWinHeight = tmpWidth;
} else {
_initWinWidth = $(window).width();
_initWinHeight = $(window).height();
}
}
var h = $(window).height();
_display = _activeElement !== null && _initWinHeight > h;
$.each(_callback, function(k, v) {
v.apply(null, [_display, _activeElement]);
});
_landscape = _landscape2;
}, 200);
});
當存在聚焦元素,且窗口高度比初始化時的窗口高度小時,即認為鍵盤出現了。
_display = _activeElement !== null && _initWinHeight > h;
鍵盤的問題解決了,我們需要解決聚焦元素的位置問題,否則可能會出現聚焦元素不在可視區域的情況,用戶茫然不知當前輸入的是啥。需要注意的是在iOS6下,系統會自動定位到聚焦的元素,但升級后的iOS7就沒那么“正常”了,表現的跟Android比較類似,所以我們只對非iOS6以及iOS7的做處理即可。
// 聚焦且鍵盤顯示時,修正輸入框位置 // iOS6會自動定位到輸入框,但還是需要refresh位置 // iOS7不會自動定位到輸入框,表現跟Android類似 if ((!$.os.ios || _ios7) && display && focusElement) { offset = $.type(offset) == 'number' ? offset : 5; var el = $(focusElement), winHeight = $(window).height(), top = el.height() + el.offset().top + offset; // iScrollInstance.y為負值 if (top - iScrollInstance.y > winHeight) { iScrollInstance.scrollTo(0, winHeight - top + iScrollInstance.y, 0); } // iOS7下聚焦鍵盤出現后,輸入框沒聚焦,這里設置下 _ios7 && focusElement.focus(); }
說到iOS7,還有一個地方比較怪異,當點擊輸入框,鍵盤會出現,但是輸入框沒有聚焦。需要手動再點擊一次。初步排查是iScroll4的問題,但沒搞懂是哪出問題了,所以iKeyboardScroll4里對這些情況做了處理,暫時解決了這一問題。
移動側WebApp坑還是比較多,需要不斷的積累經驗才行啊~
