簡體   English   中英

iOS 通過溢出滾動禁用頁面滾動:觸摸

[英]iOS Disable Page Scrolling with overflow-scrolling: touch

假設我們希望通過“添加到主屏幕”使 web 應用程序感覺像是本機應用程序。 第一步是禁用默認滾動。 很簡單,對吧?

// window or document
window.addEventListener("touchmove", function(event) {
    // no more scrolling
    event.preventDefault();
}, false);

在您將overflow-scrolling添加到混合中之前,這一切都很好。 准確地說,在 iOS 上應該是-webkit-overflow-scrolling: touch

/* #scrollable happens to be a ul */
#scrollable {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

通過添加事件預防,容器中的硬件加速滾動不起作用,顯然不是預期的效果。

顯而易見的解決方案如下所示:

// you could do this for multiple elements, of course
var scrollable = document.querySelector("#scrollable");
scrollable.addEventListener("touchmove", function(event) {
    // no more bubbling :)
    event.stopPropagation();
}, false);

此解決方案引入了一個問題,但是,如果您嘗試在#scrollable向左或向右滾動,它會恢復為默認滾動偵聽器。 顯然,您應該監視事件以查看touchmove事件是向左跟蹤還是向右跟蹤,對嗎? 不幸的是,不,因為它也將在我不完全理解的情況下在容器中垂直滾動時恢復到默認滾動偵聽器。

怎么辦? 更糟糕的是,我們最好能夠處理單個li上的click或類似點擊的事件(閱讀: touchstart ):

var items = scrollable.querySelectorAll("#scrollable li");
for (var item = 0; item < items.length; item++) {
    items[item].addEventListener("touchstart", function() {
        // handle the touch start
    }, false);
}

為了解決這個問題,我們可以轉向簡單地使用click事件,但由於點擊和響應之間的延遲,默認目標是使 web 應用“感覺”原生。 為了解決這個問題,我們將為touchstarttouchend添加一個事件監聽touchend

var items = scrollable.querySelectorAll("#scrollable li");
var activeItem = null, startTouch = null;
for (var item = 0; item < items.length; item++) {
    items[item].addEventListener("touchstart", function(event) {
        startTouch = event.touches[0];
        activeItem = this;
    }, false);
    items[item].addEventListener("touchend", function(event) {
        var touch = event.changedTouches[0];
        var deltaX = touch.pageX - startTouch.pageX
        var deltaY = touch.pageY - startTouch.pageY;
        // require the touchstart to be within 10 pixels of the touchend
        if (deltaX * deltaX + deltaY * deltaY <= 100)
            // handle "click" event
    }, false);
}

這一切都很好,但我們仍然沒有解決默認頁面滾動控制一些touchmove事件的問題。 有任何想法嗎?

嘗試交換window的邏輯和scrollable元素偵聽器,如下所示:

// window or document
window.addEventListener("touchmove", function(event) {
  if (!event.target.classList.contains('scrollable')) {
    // no more scrolling
    event.preventDefault();
  }
}, false);

// No special listeners needed on .scrollable elements

這樣,您只能在嘗試滾動不可滾動元素時阻止默認值。

您仍然會遇到一個問題,即在可滾動內容的頂部/底部開始拖動可能會導致整個應用程序“彈跳”。 要解決此問題,請參閱Joe Lambert 的 ScrollFix

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM