1.-webkit-overflow-scrolling帶來的相關問題。
-webkit-overflow-scrolling?屬性控制元素在移動設備上是否使用滾動回彈效果.
其具有兩個屬性:
auto: 使用普通滾動, 當手指從觸摸屏上移開楞泼,滾動會立即停止寡具。
touch: 使用具有回彈效果的滾動, 當手指從觸摸屏上移開锌蓄,內(nèi)容會繼續(xù)保持一段時間的滾動效果熬尺。繼續(xù)滾動的速度和持續(xù)的時間和滾動手勢的強烈程度成正比褂始。同時也會創(chuàng)建一個新的堆棧上下文夺欲。
在查找相關資料時跪帝,有看見這樣一個問題,雖然在開發(fā)過程中并沒有遇見些阅,但防患未然還是做一個記錄伞剑。
如果在-webkit-overflow-scrolling:touch屬性的元素上,想通過動態(tài)添加內(nèi)容來撐開容器市埋,觸發(fā)滾動黎泣,頁面會卡住不動。(測試中未復現(xiàn)此bug)缤谎。
給出的解決方案:給內(nèi)容最小高度101%抒倚;主動觸發(fā)scrollbar。
你也可以直接加偽元素上
滾動的盒子:after { min-height: calc(100% + 1px)}
2.IOS回彈現(xiàn)象產(chǎn)生的問題
滾動元素的滾動條在頂部時做下拉操作坷澡,或滾動條在底部時做上滑操作時托呕,引發(fā)窗口反彈。此時滾動元素的滾動事件暫時失效。
解決方案可引用inobounce.js项郊,其原理為:
1.判斷當前瀏覽器是否支持-webkit-overflow-scrolling:touch屬性馅扣。
2若存在,監(jiān)聽touchstart和touchmove事件
window.addEventListener('touchstart ',handleTouchstart, { passive : false });
window.addEventListener('touchmove',handleTouchmove,{ passive : false });
在touchstart中獲取觸摸點的y(startY)坐標
在touchmove中通過循環(huán)查找呆抑,如果當前事件源的祖先元素具有-webkit-overflow-scrolling:touch屬性岂嗓,且完全計算屬性overflow-y==auto或者overflow-y==scroll 則進一步做判斷汁展,否則阻止默認事件鹊碍。
var handleTouchmove = function(evt) {
var el = evt.target; //獲取當前事件源
var zoom = window.innerWidth / window.document.documentElement.clientWidth;
if (evt.touches.length > 1 || zoom !== 1) {
return;
}//檢查是否存在可滾動的祖先元素
while (el !== document.body && el !== document) {//獲取樣式屬性
var style = window.getComputedStyle(el);
if (!style) {?// 如果遇到無法計算樣式的元素,請退出
break;
}
//忽略input元素
if (el.nodeName === 'INPUT' && el.getAttribute('type') === 'range') {
return;
}
var scrolling = style.getPropertyValue('-webkit-overflow-scrolling');
var overflowY = style.getPropertyValue('overflow-y');
var height = parseInt(style.getPropertyValue('height'), 10);
var isScrollable = scrolling === 'touch' && (overflowY === 'auto' || overflowY === 'scroll');
var canScroll = el.scrollHeight > el.offsetHeight;// 如果檢查的元素具有回彈屬性食绿,且可滾動侈咕。?
if (isScrollable && canScroll) {//獲取當前觸摸點的y(?curY?)坐標?
var curY = evt.touches ? evt.touches[0].screenY : evt.screenY;//滾動條位于頂部,且用戶進行下拉操作
var isAtTop = (startY <= curY && el.scrollTop === 0);//滾動條位于底部器紧,且用戶進行上滑操作耀销,此時窗口也會反彈
var isAtBottom = (startY >= curY && el.scrollHeight - el.scrollTop === height);//?這兩種情況下窗口會都會反彈,為避免這種現(xiàn)象铲汪,此時阻止默認事件
// Stop a bounce bug when at the bottom or top of the scrollable element
if (isAtTop || isAtBottom) {
evt.preventDefault();
}
return;
}
// 測試元素不具有回彈屬性熊尉,且不可滾動,繼續(xù)測試其父元素
el = el.parentNode;
}// 祖先元素都不具有回彈屬性掌腰,且不可滾動狰住,則阻止默認事件
evt.preventDefault();
};
Element.scrollHeight?這個只讀屬性是一個元素內(nèi)容高度的度量,包括由于溢出導致的視圖中不可見內(nèi)容齿梁。
以上方式雖然可解決當滾動條到達底部或頂部時催植,窗口整體下移或上移,導致內(nèi)部滾動事件暫時性失效問題
不過也使得滾動容器自身回彈效果的部分丟失勺择。
可改進的一個想法的記錄:
???? 在touchstart事件中判斷祖先元素是否具有回彈屬性创南。且當滾動條在頂部或底部時對應的將滾動條的位置置為1或底部滾動最大距離-1。
????阻止其他自身或祖先元素不具有滾動條的元素的默認事件省核。
????在做測試時發(fā)現(xiàn)在非輕觸時是可以實現(xiàn)的稿辙,但是觸摸事件急促短暫時,窗口依舊整體下移气忠。
3.移動端喚起軟鍵盤引起的問題
當input框聚焦時邓深,移動端喚起軟鍵盤,頁面整體太高笔刹,當軟鍵盤消失后芥备,如果input框的祖先元素是固定定位,則元素視覺上回到之前的位置舌菜,但實際上窗口的滾動條為負萌壳,頁面出現(xiàn)錯位現(xiàn)象,如果祖先元素是絕對定位,元素會停留在軟鍵盤存在時的位置袱瓮,需手動滑動頁面恢復原狀缤骨。
解決方法:中心思想是在失焦事件時設置window.scroll(0,0)。
但是尺借,當頁面內(nèi)存在兩個以上的輸入框時绊起,在輸入框切換之間,會存在聚焦失焦聚焦事件燎斩,如果未做判斷虱歪,此時會出現(xiàn)輸入框切換間頁面上下抖動。
解決方式:在失焦事件中設置定時器栅表,定時器內(nèi)部設置window.scroll(0,0)在聚焦事件中清除定時器笋鄙。即保證了在軟鍵盤存在時不觸發(fā)window.scroll(0,0)。