問題描述

我為我的公司建立了一個小型的 HTML5 Web 應用程式。

此應用程式顯示專案列表,一切正常。

該應用程式主要用於 Android 手機和 Chrome 瀏覽器。此外,該網站儲存在主螢幕上,所以 Android 管理整個事情作為一個應用程式 (使用 WebView 我猜) 。

Chrome Beta(我也認為 Android 系統 WebView) 已經推出了 「下拉重新整理」 功能 (See this link for example) 。

這是一個方便的功能,但我想知道是否可以停用一些元標記 (或 JavaScript 東西),因為重新整理可以輕鬆觸發使用者導航列表和整個應用程式重新載入。

這也是應用程式不需要的功能。

我知道此功能僅在 Chrome 測試版中可用,但我也感到這是登陸在穩定的應用程式。

謝謝!

編輯:我已經解除安裝了 Chrome 測試版,並且固定到主螢幕的連結現在使用穩定的 Chrome 開啟。因此,固定連結從 Chrome 開始,而不是使用網路檢視。

編輯:今天 (2015-03-19)pull-down-to-refresh 已經來到了穩定的鍍 chrome 。

編輯:從 @Evyn 答案我遵循 this link 並得到這個 JavaScript /jquery 程式碼工作。



var lastTouchY = 0;
var preventPullToRefresh = false;

$('body').on('touchstart', function (e) {
    if (e.originalEvent.touches.length != 1) { return; }
    lastTouchY = e.originalEvent.touches[0].clientY;
    preventPullToRefresh = window.pageYOffset == 0;
});

$('body').on('touchmove', function (e) {
    var touchY = e.originalEvent.touches[0].clientY;
    var touchYDelta = touchY - lastTouchY;
    lastTouchY = touchY;
    if (preventPullToRefresh) {
        // To suppress pull-to-refresh it is sufficient to preventDefault the first overscrolling touchmove.
        preventPullToRefresh = false;
        if (touchYDelta > 0) {
            e.preventDefault();
            return;
        }
    }
});

正如 @bcintegrity 指出的,我希望將來能夠提供站點清單解決方案 (和/或 meta-tag) 。

此外,歡迎有關上述程式碼的建議。

最佳解決方案

透過執行以下操作可以有效地防止 pull-to-refresh 效果的預設動作:

  1. 防止觸控序列的某些部分,包括以下任何內容 (以最具破壞性至最不破壞性的順序):

    • 一個。整個觸控流 (不理想) 。

    • 灣所有頂部過捲動觸控。

    • C 。第一個頂部過捲動 touchmove 。

    • 天。第一個頂部過捲動 touchmove 只有當 1) 初始觸控發生時,頁面 y 滾動偏移為零,2) 觸控式螢幕將引起頂部過度捲動。

  2. 在適當的情況下,對 touch-targeted 元素應用 「touch-action:無」,停用觸控序列的預設動作 (包括 pull-to-refresh) 。

  3. 將 「overflow-y:hidden」 應用於 body 元素,如果需要,可以使用 div 進行可滾動的內容。

  4. 透過 chrome://標誌 (disable-pull-to-refresh-effect) 在本地停用效果。

See more

次佳解決方案

目前您只能透過 chrome://flags/#disable-pull-to-refresh-effect 停用此功能 – 直接從您的裝置開啟。

您可以嘗試捕捉 touchmove 事件,但是獲得可接受的結果很有可能。

第三種解決方案

我使用 MooTools,我已經建立了一個類來停用目標元素上的重新整理,但它的關鍵是 (native JS):

var target = window; // this can be any scrollable element
var last_y = 0;
target.addEventListener('touchmove', function(e){
    var scrolly = target.pageYOffset || target.scrollTop || 0;
    var direction = e.changedTouches[0].pageY > last_y ? 1 : -1;
    if(direction>0 && scrolly===0){
        e.preventDefault();
    }
    last_y = e.changedTouches[0].pageY;
});

我們在這裡所做的就是找到 touchMove 的 y 方向,如果我們向下移動螢幕並且目標滾動是 0,我們停止事件。因此,沒有重新整理。

這意味著我們正在為每個’move’ 開槍,這可能是昂貴的,但是迄今為止我發現的最佳解決方案…

第四種方案

AngularJS

我已經成功地停用了這個 AngularJS 指令:

//Prevents "pull to reload" behaviour in Chrome. Assign to child scrollable elements.
angular.module('hereApp.directive').directive('noPullToReload', function() {
    'use strict';

    return {
        link: function(scope, element) {
            var initialY = null,
                previousY = null,
                bindScrollEvent = function(e){
                    previousY = initialY = e.touches[0].clientY;

                    // Pull to reload won't be activated if the element is not initially at scrollTop === 0
                    if(element[0].scrollTop <= 0){
                        element.on("touchmove", blockScroll);
                    }
                },
                blockScroll = function(e){
                    if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
                        e.preventDefault();
                    }
                    else if(initialY >= e.touches[0].clientY){ //Scrolling down
                        //As soon as you scroll down, there is no risk of pulling to reload
                        element.off("touchmove", blockScroll);
                    }
                    previousY = e.touches[0].clientY;
                },
                unbindScrollEvent = function(e){
                    element.off("touchmove", blockScroll);
                };
            element.on("touchstart", bindScrollEvent);
            element.on("touchend", unbindScrollEvent);
        }
    };
});

一旦使用者向下滾動就可以立即停止觀看,因為拉動重新整理沒有被觸發的機會。

同樣,如果 scrolltop > 0,事件不會被觸發。在我的實現中,我在 touchstart 上繫結 touchmove 事件,只有當 scrollTop <= 0 。一旦使用者向下滾動 (initialY >= e.touches[0].clientY),我將其解除繫結。如果使用者向上滾動 (previousY < e.touches[0].clientY),那麼我呼叫 preventDefault()

這樣可以節省我們不必要地看滾動事件,但是阻止過度的滾動。

jQuery

如果你使用 jQuery,這是未經測試的等價物。 element 是一個 jQuery 元素:

var initialY = null,
    previousY = null,
    bindScrollEvent = function(e){
        previousY = initialY = e.touches[0].clientY;

        // Pull to reload won't be activated if the element is not initially at scrollTop === 0
        if(element[0].scrollTop <= 0){
            element.on("touchmove", blockScroll);
        }
    },
    blockScroll = function(e){
        if(previousY && previousY < e.touches[0].clientY){ //Scrolling up
            e.preventDefault();
        }
        else if(initialY >= e.touches[0].clientY){ //Scrolling down
            //As soon as you scroll down, there is no risk of pulling to reload
            element.off("touchmove");
        }
        previousY = e.touches[0].clientY;
    },
    unbindScrollEvent = function(e){
        element.off("touchmove");
    };
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);

當然,純 JS 也可以實現。

第五種方案

純 CSS 的最佳解決方案:

body {
    width: 100%;
    height: 100%;
    display: block;
    position: absolute;
    top: -1px;
    z-index: 1;
    margin: 0;
    padding: 0;
    overflow-y: hidden;
}
#pseudobody {
    width:100%;
    height: 100%;
    position: absolute;
    top:0;
    z-index: 2;
    margin: 0;
    padding:0;
    overflow-y: auto;
}

看這個演示:https://jsbin.com/pokusideha/quiet

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇