前幾天在幫一個同事看了個問題,就是他的老項目裏(用的jquery)寫的,用iScroll插件作滾動加載的時候,在他的iphone7手機上,指定區域只能移動6px左右,這明顯不正常,其餘同事包括個人(8plus)是正常的,而後幫他找緣由, 首先查看了下iScroll的版本4.25,好像也沒問題啊。jquery
onBeforeScrollStart: function(e) {
e.preventDefault();
}
複製代碼
此方法是在_start裏進行了調用,目的是爲了阻止瀏覽器默認動做的執行,防止在滑動的過程當中進行干擾,同時也就阻止了滑動區域裏元素的事件的觸發,這種處理方式也直接致使了必需要在_end方法中再次觸發元素的點擊事件。android
if (target.tagName != 'SELECT' && target.tagName != 'INPUT'
&& target.tagName != 'TEXTAREA') {
ev = document.createEvent('MouseEvents');
ev.initMouseEvent('click', true, true,
e.view, 1,point.screenX,
point.screenY, point.clientX,
point.clientY,e.ctrlKey,
e.altKey, e.shiftKey,
e.metaKey,0, null);
ev._fake = true;
target.dispatchEvent(ev);
}
複製代碼
這個處理方式就是順承了上面所提到的阻止了瀏覽器默認行爲後,對滑動區域除select、input、textarea外的元素觸發click事件,已完成對click綁定事件的調用。web
因爲onBeforeScrollStart是在_start方法中進行的調用,e.preventDefault();阻止了元素的默認行爲,從而致使了元素綁定事件的失效,必須在_end操做結束後進行綁定事件的模擬調用,原始的iScroll源代碼中在_end中最後建立了click事件的模擬,可是這裏必需要清楚的一個原理就是,click實際上是要依賴於其餘事件的:chrome
1 普通pc網頁中,click須要依賴於mousedown、mouseup的相繼觸發瀏覽器
2 移動webkit中,click則須要依賴於touchstart、touchend(實際mousedown,mouseup在移動webkit上也存在)的相繼觸發 「相繼觸發」的意思就是中間不會夾雜有其餘的事件類型,這也就很容易理解iScroll中在_end中對模擬事件調用的條件了,必需要判斷that.moved才能直接觸發模擬事件。bash
iScroll中與_start、_move、_end相關的三個事件類型是按照以下的規則來設置的:框架
START_EV = hasTouch ? 'touchstart' : 'mousedown'
MOVE_EV = hasTouch ? 'touchmove' : 'mousemove'
END_EV = hasTouch ? 'touchend' : 'mouseup'
複製代碼
經測試,部分手機裏默認瀏覽器裏會默認全部元素都有一個默認的click事件(測試結果顯示鼠標事件中默認事件包含mouseup,mousedown,click,dblclick在移動webkit上不支持,爲系統放大功能),e.preventDefault時會阻止掉默認click事件的執行,必需要人爲的在_end結束以後模擬click事件的調用,而其餘正常手機即便調用了e.preventDefault也不會阻止click事件的觸發,由於這些手機的默認瀏覽器上的元素的click事件的cancelable屬性不爲true,不能夠被preventDefault取消掉,會正常執行,而若是在_end中模擬了click事件則將會致使click的重複調用(在有toggle狀態的事件上很是明顯),所以折中的方式參見下面的解決方案。iphone
onBeforeScrollStart: function (e) {
//e.preventDefault();
}
複製代碼
onBeforeScrollMove:function (e) {
e.preventDefault();
}
複製代碼
以保證手機上的正常滑動免受瀏覽器默認行爲影響(以下滑時會有窗口的scroll事件),固然若是這裏不添加的話也能夠在document的END_EV中阻止瀏覽器默認行爲測試
iscroll.js是Matteo Spinelli開發的一個js文件,使用原生js編寫,不依賴與任何js框架。旨在解決移動webkit系瀏覽器的區域滾動問題,兼容mobile、safari、android默認瀏覽器、safari、chrome、firefox5+、opera11+、IE9+及其餘webkit核心瀏覽器。spa
最後,我在這次解決滾動失效的過程當中,針對該頁面作了一個最簡單的處理以下:
// 獲取所須要滾動區域的元素
var scrollPage = document.querySelector('.scrollPage');
// 取消事件默認動做
scrollPage.addEventListener('touchmove',function(e){
e.preventDefault();
});
複製代碼
這樣頁面便可恢復滾動效果了。