禁用机器人的铬下拉刷新功能

我已经为我的公司创建了一个小的 HTML5网络应用程序。

这个应用程序显示一个项目列表,一切工作正常。

该应用程序主要用于 Android 手机和 Chrome 浏览器。此外,该网站保存在主屏幕上,所以安卓管理整个事情作为一个应用程序(我猜是通过网络视图)。

ChromeBeta (我认为也是 Android 系统的 WebView)引入了“下拉刷新”功能(See this link for example)。

这是一个方便的功能,但我想知道它是否可以禁用一些元标记(或 javascript 的东西) ,因为刷新可以很容易地触发由用户导航列表和整个应用程序重新加载。

这也是应用程序不需要的特性。

我知道这个功能仍然只在 Chrome 测试版中有效,但是我有一种感觉,这个功能也将登陆到这个稳定的应用程序中。

谢谢!

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

编辑: 今天(2015-03-19)下拉刷新已经到了稳定的铬。

编辑: 从@Evyn 的回答,我按照 这个链接得到了这个 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;
}
}
});

正如@bc 完整性所指出的,我希望将来能有一个站点清单解决方案(和/或元标记)。

此外,欢迎对上述守则提出建议。

99373 次浏览

目前你只能通过 Chrome://Flag/# disable-pull-to-refresh-effect禁用这个功能-直接从你的设备打开。

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

我使用 MooTools,并且我已经创建了一个 Class 来禁用目标元素的刷新,但是它的关键是(本机 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;
});

我们在这里要做的就是找到触摸操作的 y 方向,如果我们沿着屏幕向下移动,目标滚动是0,我们就停止事件。因此,没有刷新。

这意味着我们正在采取一切“行动”,这可能是昂贵的,但是是我迄今为止找到的最好的解决方案..。

通过执行以下任何操作,都可以有效地防止 pull-to-refresh 效果的默认操作:

  1. 对触摸序列的某些部分进行 preventDefault处理,包括以下任何一项(按破坏性最大到破坏性最小的顺序排列) :
    • 整个触摸流(不理想)。
    • 所有顶部过卷的触摸动作。
    • 第一个上翻滚的触摸动作。
    • D.只有在下列情况下才会出现第一次顶部超滚动: 1)当页面 y 滚动偏移量为零时,初始触动发生; 2)触动会导致顶部超滚动。
  2. 在适当的情况下,将“ touch-action: none”应用于触摸目标元素,禁用触摸序列的默认操作(包括拉到刷新)。
  3. 对 body 元素应用“ overflow-y: hidden”,必要时对可滚动内容使用 div。
  4. 通过 chrome://flags/#disable-pull-to-refresh-effect在本地禁用效果)。

再看看

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,事件也不会被触发。在我的实现中,只有当 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 也可以达到同样的效果。

简单的 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>

注意,overflow-y 不是继承的,因此需要在 ALL 块元素上设置它。

你可以简单地使用 jQuery:

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

纯 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 刷新操作的 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>

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

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

我发现设置您的 尸体 CSS 溢出,隐藏是最简单的方法。如果您确实希望有一个滚动应用程序页面,那么只需使用具有滚动特性的 div 容器即可。

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

scrollTo(0, 1)

由于铬不滚动,如果它不在滚动位置 0这将阻止铬做拉刷新。

如果它仍然不工作,尝试也这样做,当页面加载。

纯 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);

2019年的简单解决方案 +

Chrome63添加了一个 css 属性来帮助解决这个问题。通读一下 本指南由谷歌提供,了解一下你是如何处理它的。

这是他们的 TL: DR

CSS 过卷行为属性允许开发人员重写 浏览器的默认溢出滚动行为 内容的顶部/底部。用例包括禁用拉取刷新 移动,消除过卷发光和橡皮筋效果, 并防止页面内容在 模式/重叠模式/重叠模式。

为了让它正常工作,你只需要在 CSS 中添加以下内容:

body {
overscroll-behavior: contain;
}

它目前也只是 Chrome,Edge 和 Firefox 的 支持版本,但我相信 Safari 很快就会添加它,因为他们看起来已经完全支持服务工作者和 PWA 的未来。

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

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

你可以试试这个

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

这对我很有效:

html {
overscroll-behavior-y: contain;
}