本文是zawa同事寫的一篇博文,相信不少在webapp開發中的同窗使用iscroll4會遇到的該問題,問過zawa兄的建議,在這裏分享給你們,但願能幫助到各位~html
原文地址:http://www.zawaliang.com/2013/10/443.htmlios
問題:在使用了iScroll4的容器內,當表單元素focus聚焦後鍵盤出現時,可能會存在iScroll區域高度不更新,滾動異常問題;並且當前聚焦的表單元素可能不出如今可視區域內,影響用戶體驗。git
iKeyboardScroll4就是這麼一個解決方案
Github見:https://github.com/zawaliang/iKeyboardScroll4github
現在大多數機型都支持onorientationchange事件,iScroll4在不支持onorientationchange事件的機型中使用onresize事件來對滾動區域進行自動刷新操做。因此上面說的表單狀況,在大多數機型裏都會存在高度不刷新的狀況。web
RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
那麼如今的問題就是檢測鍵盤出現與否,而後調用refresh接口刷新滾動區域高度。因爲沒有相應的接口來檢測鍵盤狀態,因此咱們經過onresize來檢測窗口高度變化,配合當前元素的聚焦狀態來模擬鍵盤狀態。同時須要考慮在鍵盤出現時翻屏的狀況。app
因爲不肯定orientationchange與onresize哪一個先觸發,並且Android下orientationchange以後獲取高度存在時間差,因此這裏統一到onresize進行處理。webapp
$(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); });
當存在聚焦元素,且窗口高度比初始化時的窗口高度小時,即認爲鍵盤出現了。spa
_display = _activeElement !== null && _initWinHeight > h;
鍵盤的問題解決了,咱們須要解決聚焦元素的位置問題,不然可能會出現聚焦元素不在可視區域的狀況,用戶茫然不知當前輸入的是啥。須要注意的是在iOS6下,系統會自動定位到聚焦的元素,但升級後的iOS7就沒那麼「正常」了,表現的跟Android比較相似,因此咱們只對非iOS6以及iOS7的作處理便可。code
// 聚焦且鍵盤顯示時,修正輸入框位置 // 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裏對這些狀況作了處理,暫時解決了這一問題。htm
移動側WebApp坑仍是比較多,須要不斷的積累經驗才行啊~