我为我的公司创建了一个小型HTML5网络应用程序。
此应用程序显示项目列表,一切正常。
该应用程序主要用于Android手机和Chrome浏览器。此外,该网站保存在主屏幕上,因此Android管理整个应用程序(使用WebView我猜)。
Chrome Beta(我认为还有Android系统WebView)引入了“下拉刷新”功能(See this link for example)。
这是一个方便的功能,但我想知道是否可以使用某些元标记(或javascript内容)禁用它,因为用户可以在导航列表时轻松触发刷新并重新加载整个应用。
这也是应用程序不需要的功能。
我知道此功能仅在Chrome测试版中可用,但我感觉这也是稳定的应用程序。
谢谢!
编辑:我已卸载Chrome测试版,现在可以使用稳定的Chrome打开固定到主屏幕的链接。因此,固定链接始于Chrome,而不是webview。
编辑:今天(2015-03-19),下拉到刷新已经到了稳定的镀铬。
编辑:来自@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指出的那样,我希望将来有一个网站清单解决方案(和/或元标记)。
此外,欢迎对上述代码提出建议。
答案 0 :(得分:138)
通过执行以下任一操作,可以有效防止拉动刷新效果的默认操作:
preventDefault
触摸序列的某些部分,包括以下任何一种(按破坏性最小到破坏性最小的顺序):
touch-action: none
”应用于触控目标元素(如果适用),禁用触摸序列的默认操作(包括“拉动 - 刷新”)。overflow-y: hidden
”应用于body元素,必要时使用div作为可滚动内容。chrome://flags/#disable-pull-to-refresh-effect
)在本地停用效果。答案 1 :(得分:67)
Chrome 63(2017年12月5日发布)添加了一个css属性来帮助解决这个问题。请仔细阅读this guide by Google,以便了解如何处理它。
这是他们的TL:DR
CSS overscroll-behavior属性允许开发人员覆盖 到达时浏览器的默认溢出滚动行为 内容的顶部/底部。用例包括禁用pull-to-refresh 移动功能,消除过卷发光和橡皮筋效果, 并阻止页面内容滚动时的页面内容 模态/重叠。
要使其正常运行,您只需在CSS中添加:
body {
overscroll-behavior: contain;
}
目前Chrome,Edge和Firefox也只有supported,但我确信Safari会很快添加它,因为它们似乎完全支持服务工作者和PWA的未来。
答案 2 :(得分:15)
目前,您只能通过chrome://flags/#disable-pull-to-refresh-effect停用此功能 - 直接在您的设备上打开。
您可以尝试捕捉touchmove
事件,但实现可接受的结果的可能性非常小。
答案 3 :(得分:8)
我使用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,我们就会停止事件。因此,没有刷新。
这意味着我们正在开展每一项行动,这可能会很昂贵,但这是迄今为止我找到的最佳解决方案......
答案 4 :(得分:5)
我已使用此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
时绑定touchstart上的touchmove事件。一旦用户向下滚动(initialY >= e.touches[0].clientY
),我就会解除绑定。如果用户向上滚动(previousY < e.touches[0].clientY
),则会调用preventDefault()
。
这使我们无需担心滚动事件,但阻止了过度滚动。
如果您使用的是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也可以实现同样的目标。
答案 5 :(得分:5)
经过几个小时的尝试,这个解决方案适合我
$("html").css({
"touch-action": "pan-down"
});
答案 6 :(得分:4)
我使用标准的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>
答案 7 :(得分:3)
纯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;
}
答案 8 :(得分:3)
我发现设置正文 CSS 溢出-y:隐藏是最简单的方法。如果您确实想要一个滚动的应用程序页面,您可以使用具有滚动功能的div容器。
答案 9 :(得分:2)
几周以来,我发现我用来禁用Chrome刷新操作的javascript功能不再适用。我已经解决了这个问题:
$(window).scroll(function() {
if ($(document).scrollTop() >= 1) {
$("html").css({
"touch-action": "auto"}
);
} else {
$("html").css({
"touch-action": "pan-down"
});
}
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
&#13;
答案 10 :(得分:1)
请注意,overflow-y不会被继承,因此您需要在所有块元素上设置它。
您可以通过以下方式使用jQuery执行此操作:
$(document.body).css('overflow-y', 'hidden');
$('*').filter(function(index) {
return $(this).css('display') == 'block';
}).css('overflow-y', 'hidden');
答案 11 :(得分:0)
我所做的是在touchstart
和touchend
/ touchcancel
事件中添加以下内容:
scrollTo(0, 1)
由于chrome不在scrollY位置0
上滚动,因此这会阻止chrome进行刷新。
如果它仍然不起作用,请尝试在页面加载时执行此操作。
答案 12 :(得分:0)
Pure 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);
答案 13 :(得分:0)
我通过以下方法解决了从下拉到刷新的问题:
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
答案 14 :(得分:0)
您可以尝试
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