禁用 android 的 chrome 下拉刷新功能
Posted
技术标签:
【中文标题】禁用 android 的 chrome 下拉刷新功能【英文标题】:Disabling android's chrome pull-down-to-refresh feature 【发布时间】: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 上的数据... 【参考方案1】:通过执行以下任一操作,可以有效防止拉动刷新效果的默认动作:
preventDefault
’ing 触摸序列的某些部分,包括以下任何一项(按照破坏性最大到破坏性最小的顺序):
一个。整个触摸流(不理想)。
乙。所有顶部滚动触摸动作。
c。第一个顶部滚动触摸动作。
d.仅当 1) 初始 touchstart 发生在页面 y 滚动偏移量为零时以及 2) touchmove 会导致顶部过度滚动时,才进行第一次顶部过度滚动。
在适当的情况下将“@987654323@”应用于以触摸为目标的元素,禁用触摸序列的默认操作(包括下拉刷新)。
将“overflow-y: hidden
”应用于 body 元素,如有必要,可使用 div 滚动内容。
通过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 仍然显示发光效果 + 原生拉动刷新 developers.google.com/web/updates/2017/11/overscroll-behavior这个链接也可以解释的更好【参考方案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中使用这个:htmltouch-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 > 0
,则不会触发该事件。在我的实现中,我在 touchstart 上绑定 touchmove 事件,仅当 scrollTop <= 0
时。一旦用户向下滚动(initialY >= e.touches[0].clientY
),我就会取消绑定它。如果用户向上滚动(previousY < 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 above 的body: 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"
);
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
【讨论】:
【参考方案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】:我所做的是在touchstart
和touchend
/touchcancel
事件中添加以下内容:
scrollTo(0, 1)
如果 chrome 不在 scrollY 位置 0
上不会滚动,这将阻止 chrome 进行拉动刷新。
如果仍然无法正常工作,请尝试在页面加载时也这样做。
【讨论】:
【参考方案15】:我用这个解决了下拉刷新问题:
html, body
width: 100%;
height: 100%;
overflow: hidden;
【讨论】:
以上是关于禁用 android 的 chrome 下拉刷新功能的主要内容,如果未能解决你的问题,请参考以下文章
在 Chrome 开发人员工具中,如何禁用刷新元素周围的突出显示?