【问题标题】:Disabling android's chrome pull-down-to-refresh feature禁用 android 的 chrome 下拉刷新功能
【发布时间】:2015-05-14 12:23:17
【问题描述】:

我为我的公司创建了一个小型 HTML5 Web 应用程序。

此应用程序显示项目列表,一切正常。

该应用程序主要用于安卓手机和Chrome浏览器。此外,该网站保存在主屏幕上,因此 Android 将整个内容作为应用程序进行管理(我猜是使用 WebView)。

Chrome Beta(我认为也是 Android System WebView) 引入了“下拉刷新”功能 (See this link for example)。

这是一个方便的功能,但我想知道是否可以使用一些元标记(或 javascript 内容)禁用它,因为用户在导航列表时可以轻松触发刷新,并且重新加载整个应用程序。

这也是应用程序不需要的功能。

我知道这个功能仍然只在 Chrome 测试版中可用,但我感觉它也登陆了稳定的应用程序。

谢谢!

编辑:我已经卸载了 Chrome Beta,固定到主屏幕的链接现在可以使用稳定的 Chrome 打开。所以固定链接以 Chrome 开头,而不是 webview。

编辑:今天(2015 年 3 月 19 日)下拉刷新已进入稳定版 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 指出的那样,我希望将来有一个站点清单解决方案(和/或元标记)。

欢迎对以上代码提出建议。

【问题讨论】:

  • 是的,这真的很糟糕。处于表格中间并滚动到顶部太远,它刷新并丢失了所有内容。这是一个延迟的默认功能,如果我想刷新,我点击刷新图标!
  • 如果可以在我的网络应用清单中禁用此功能会很好。不幸的是,我的网络应用程序上的每个页面都有可滚动的内容,因此几乎无法在不刷新的情况下进行导航。我有点心动了。 ://
  • 这是个好信息。我讨厌禁用下拉刷新功能的网站。我想开发一项功能,使刷新工作不受页面内容的影响。
  • 作为 Web 开发人员,下拉刷新与数据驱动的网站不兼容,因为它会重新加载应用程序。它使用户无法在不刷新整个页面的情况下滚动到页面顶部。我 100% 支持 Chrome,希望他们删除这个反功能。
  • 我遇到了这个GC“功能”……很多网页,很多表格,一个不小心用手指下拉,这个页面上的数据丢失了!延迟功能 IMO。默认情况下它应该是关闭的,谁需要它然后让代码它。我想知道为什么我的“客户”偶尔会丢失他们在 GC 上的数据...

标签: android html google-chrome meta-tags


【解决方案1】:

通过执行以下任一操作,可以有效防止拉动刷新效果的默认动作:

  1. preventDefault’ing 触摸序列的某些部分,包括以下任何一项(按照破坏性最大到破坏性最小的顺序):
    • 一个。整个触摸流(不理想)。
    • 乙。所有顶部滚动触摸动作。
    • c。第一个顶部滚动触摸动作。
    • d.仅当 1) 初始 touchstart 发生在页面 y 滚动偏移量为零时以及 2) touchmove 会导致顶部过度滚动时,才进行第一次顶部过度滚动。
  2. 在适当的情况下将“@​​987654323@”应用于以触摸为目标的元素,禁用触摸序列的默认操作(包括下拉刷新)。
  3. 将“overflow-y: hidden”应用于 body 元素,如有必要,可使用 div 滚动内容。
  4. 通过chrome://flags/#disable-pull-to-refresh-effect在本地禁用效果。

See more

【讨论】:

  • 谢谢@Evyn。我不敢相信这是一个快速修复!我将 body 元素的 CSS 设置为 overflow-y:hidden。
  • “chrome://flags (disable-pull-to-refresh-effect)”是如何以编程方式完成的?
  • @SomeoneSomewhere 据我所知,这并非不可能。 chrome 设置只能由用户设置 - 否则会带来安全风险
  • 对 body 元素应用“overflow-y: hidden”,使用 div 滚动内容对我有用。
  • 选项 3 太棒了,尝试了几十个选项,最后最简单的选项有效,非常感谢!
【解决方案2】:

2019+ 的简单解决方案

Chrome 63 添加了一个 CSS 属性来帮助解决这个问题。阅读this guide by Google 以了解如何处理它。

这是他们的 TL:DR

CSS overscroll-behavior 属性允许开发人员覆盖 到达时浏览器的默认溢出滚动行为 内容的顶部/底部。用例包括禁用下拉刷新 移动设备上的功能,消除过度滚动发光和橡皮筋效果, 并防止页面内容在其下方时滚动 模态/叠加。

要使其正常工作,您只需在 CSS 中添加以下内容:

body {
  overscroll-behavior: contain;
}

目前 Chrome、Edge 和 Firefox 也只有 supported,但我相信 Safari 会尽快添加它,因为它们似乎完全支持服务工作者和 PWA 的未来。

【讨论】:

  • 这是最新的答案
  • 有其他人注意到这会延迟“添加到主屏幕”chrome 横幅的出现吗?
  • 必须将其应用到 html 元素才能禁用它
  • 这仅适用于 Android , IO 上的 Chrome 仍然显示发光效果 + 原生拉动刷新
【解决方案3】:

目前您只能通过chrome://flags/#disable-pull-to-refresh-effect 禁用此功能 - 直接从您的设备打开。

您可以尝试捕捉touchmove 事件,但获得可接受结果的机会非常渺茫。

【讨论】:

  • 谢谢凯文的回答。我不能接受这个作为接受的,因为我正在寻找不依赖于用户的东西。但是这种方法有效,所以当我获得足够的声誉时,我会支持你的答案。
  • 很遗憾,这似乎是最好的解决方案 - 如果该标志设置在未来发生变化,或者您希望能够在其他站点上使用 pull 刷新...很惊讶这可以不能以编程方式控制。 :(。
  • 如果 Google 的 CEO 正在阅读此内容,请删除此功能。它似乎并不能轻松全面地禁用,并且在我看来是并非所有 Web 应用程序都想要的 Web 应用程序“功能”。
【解决方案4】:

我使用 MooTools,并且我创建了一个类来禁用目标元素的刷新,但它的关键是(原生 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,我们停止事件。因此,没有刷新。

这意味着我们会在每一个“动作”上开火,这可能会很昂贵,但这是我迄今为止找到的最佳解决方案......

【讨论】:

  • 一旦用户向下滚动,停止观看是安全的,因为拉动刷新没有被触发的机会。同样,如果scrolltop > 0,则不会触发该事件。在我的实现中,我将touchmove 事件绑定在touchstart 上,前提是scrollTop <= 0。一旦用户向下滚动(initialY >= e.touches[0].clientY),我就会取消绑定它。如果用户向上滚动(previousY < e.touches[0].clientY),那么我调用preventDefault
【解决方案5】:

经过几个小时的尝试,这个解决方案对我有用

$("html").css({
    "touch-action": "pan-down"
});

【讨论】:

  • 没有必要为此使用 jQuery。只需将“touch-action: pan-down”添加到您的 css 代码文件中即可。
  • 在你的css中使用这个:html{touch-action:pan-down}
【解决方案6】:

你可以试试这个

body {
  /* Disables pull-to-refresh but allows overscroll glow effects. */
  overscroll-behavior-y: contain;
}

例子:

https://ebidel.github.io/demos/chatbox.html

完整文档 https://developers.google.com/web/updates/2017/11/overscroll-behavior

【讨论】:

    【解决方案7】:

    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 &gt; 0,则不会触发该事件。在我的实现中,我在 touchstart 上绑定 touchmove 事件,仅当 scrollTop &lt;= 0 时。一旦用户向下滚动(initialY &gt;= e.touches[0].clientY),我就会取消绑定它。如果用户向上滚动(previousY &lt; e.touches[0].clientY),那么我调用preventDefault()

    这使我们免于不必要地观看滚动事件,但阻止过度滚动。

    jQuery

    ​​>

    如果您使用的是 jQuery,则这是 untested 等效项。 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也可以做到。

    【讨论】:

    • 我不得不使用e.originalEvent.touches[0].clientY 来完成这项工作。仍在为防止重新加载的逻辑when而苦苦挣扎。现在它似乎随机阻止向上滚动......感谢正确方向的提示!
    • 指令添加到什么元素?
    • AngularJS 指令对我来说效果很好。我们一起使用 Framework7 和 Angular(不建议这样做),并且某些东西阻止了 scrollTop 的正确行为。所以我不得不修改何时将 blockScroll 添加到元素中。但只是想说声谢谢!
    【解决方案8】:

    简单的Javascript

    我使用标准 javascript 实现。简单且易于实施。只需粘贴即可。

    <script type="text/javascript">         //<![CDATA[
         window.addEventListener('load', function() {
              var maybePreventPullToRefresh = false;
              var lastTouchY = 0;
              var touchstartHandler = function(e) {
                if (e.touches.length != 1) return;
                lastTouchY = e.touches[0].clientY;
                // Pull-to-refresh will only trigger if the scroll begins when the
                // document's Y offset is zero.
                maybePreventPullToRefresh =
                    window.pageYOffset == 0;
              }
    
              var touchmoveHandler = function(e) {
                var touchY = e.touches[0].clientY;
                var touchYDelta = touchY - lastTouchY;
                lastTouchY = touchY;
    
                if (maybePreventPullToRefresh) {
                  // To suppress pull-to-refresh it is sufficient to preventDefault the
                  // first overscrolling touchmove.
                  maybePreventPullToRefresh = false;
                  if (touchYDelta > 0) {
                    e.preventDefault();
                    return;
                  }
                }
              }
    
              document.addEventListener('touchstart', touchstartHandler, false);
              document.addEventListener('touchmove', touchmoveHandler, false);      });
                //]]>    </script>
    

    【讨论】:

    • 这对 Chrome 来说效果很好,但是在 Safari/iOS 9.2 上滚动页面顶部的 div 时导致了一些问题(转载 here)。我最终使用了来自Evyn abovebody: {overflow-y:hidden} 技巧。
    • downvoting as 不适用于 chrome,但适用于 Firefox 示例,embed.plnkr.co/rqbOVSOkKyhAgoHK2sEP 仅在移动设备中打开
    • 您粘贴的链接在我的 android 手机上也可以在 chrome 中使用。它不允许在拉动时刷新。你测试的是哪个版本的android/ios?
    • 从 Chrome 56 开始,您需要设置 passive: false 以使其工作: document.addEventListener('touchstart', touchstartHandler, { passive: false }); document.addEventListener('touchmove', touchmoveHandler, {passive: false });
    【解决方案9】:

    纯 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

    【讨论】:

    • 你真的用 chrome 在手机上测试过这个吗?
    【解决方案10】:

    我发现设置 body CSS overflow-y:hidden 是最简单的方法。如果您确实想要一个滚动的应用程序页面,您可以只使用具有滚动功能的 div 容器。

    【讨论】:

    • 似乎不可能用一条线来修复它,但它就像一个魅力,非常感谢!
    【解决方案11】:

    注意overflow-y不是继承的,所以需要在所有块元素上设置。

    您可以通过以下方式使用 jQuery 完成此操作:

            $(document.body).css('overflow-y', 'hidden'); 
            $('*').filter(function(index) {
                return $(this).css('display') == 'block';
            }).css('overflow-y', 'hidden');
    

    【讨论】:

    • 在其他答案中,这个真的很有帮助。谢谢。将此行添加到 css 中。身体{溢出-y:隐藏; }
    【解决方案12】:

    几周后,我发现我用来禁用 Chrome 刷新操作的 javascript 函数不再起作用。我做了这个来解决它:

    $(window).scroll(function() {
       if ($(document).scrollTop() >= 1) {
          $("html").css({
             "touch-action": "auto"}
          );
       } else {
          $("html").css({
             "touch-action": "pan-down"
          });
       }
    });
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案13】:

      纯js解决方案。

      // Prevent pull refresh chrome
          var lastTouchY = 0;
          var preventPullToRefresh = false;
          window.document.body.addEventListener("touchstart", function(e){
              if (e.touches.length != 1) { return; }
              lastTouchY = e.touches[0].clientY;
              preventPullToRefresh = window.pageYOffset == 0;
          }, false);
      
          window.document.body.addEventListener("touchmove", function(e){
      
              var touchY = e.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;
                  }
              }
      
          }, false);
      

      【讨论】:

        【解决方案14】:

        我所做的是在touchstarttouchend/touchcancel 事件中添加以下内容:

        scrollTo(0, 1)
        

        如果 chrome 不在 scrollY 位置 0 上不会滚动,这将阻止 chrome 进行拉动刷新。

        如果仍然无法正常工作,请尝试在页面加载时也这样做。

        【讨论】:

          【解决方案15】:

          我用这个解决了下拉刷新问题:

          html, body {
              width: 100%;
              height: 100%;
              overflow: hidden;
          }
          

          【讨论】:

            猜你喜欢
            • 2018-11-18
            • 2016-01-08
            • 1970-01-01
            • 1970-01-01
            • 2012-06-07
            • 1970-01-01
            • 2018-01-15
            • 2015-08-13
            • 2013-11-24
            相关资源
            最近更新 更多