I\'ve created a small HTML5 web application for my company.
This application displays a list of items and everything works fine.
The application is mainly us
I have successfully disabled it with this AngularJS directive:
//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);
}
};
});
It's safe to stop watching as soon as the user scrolls down, as the pull to refresh has no chance of being triggered.
Likewise, if scrolltop > 0
, the event won't be triggered. In my implementation, I bind the touchmove event on touchstart, only if scrollTop <= 0
. I unbind it as soon as the user scrolls down (initialY >= e.touches[0].clientY
). If the user scrolls up (previousY < e.touches[0].clientY
), then I call preventDefault()
.
This saves us from watching scroll events needlessly, yet blocks overscrolling.
If you are using jQuery, this is the untested equivalent. element
is a jQuery 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");
}
previousY = e.touches[0].clientY;
},
unbindScrollEvent = function(e){
element.off("touchmove");
};
element.on("touchstart", bindScrollEvent);
element.on("touchend", unbindScrollEvent);
Naturally, the same can also be achieved with pure JS.
I find setting your body CSS overflow-y:hidden is the simplest way. If you did want to have a scrolling application page you can just use a div container with scrolling features.
You can try this
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
example :
https://ebidel.github.io/demos/chatbox.html
full doc https://developers.google.com/web/updates/2017/11/overscroll-behavior
I use MooTools, and I have created a Class to disable refresh on a targeted element, but the crux of it is (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;
});
All we do here is find the y direction of the touchmove, and if we are moving down the screen and the target scroll is 0, we stop the event. Thus, no refresh.
This means we are firing on every 'move', which can be expensive, but is the best solution I have found so far ...
Chrome 63 has added a css property to help out with exactly this. Have a read through this guide by Google to get a good idea of how you can handle it.
Here is their TL:DR
The CSS overscroll-behavior property allows developers to override the browser's default overflow scroll behavior when reaching the top/bottom of content. Use cases include disabling the pull-to-refresh feature on mobile, removing overscroll glow and rubberbanding effects, and preventing page content from scrolling when it's beneath a modal/overlay.
To get it working, all you have to add is this in your CSS:
body {
overscroll-behavior: contain;
}
It is also only supported by Chrome, Edge and Firefox for now but I'm sure Safari will add it soon as they seem to be fully onboard with service workers and the future of PWA's.
After many hours of trying, this solution works for me
$("html").css({
"touch-action": "pan-down"
});