Skip to content

Instantly share code, notes, and snippets.

@Martin-Pitt
Created January 19, 2018 14:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Martin-Pitt/86930b109c3d24130f67d8bb14eea867 to your computer and use it in GitHub Desktop.
Save Martin-Pitt/86930b109c3d24130f67d8bb14eea867 to your computer and use it in GitHub Desktop.
/// Self-Contained JavaScript to prevent window scroll overflow bounce on iOS devices
/// Checks for whitelisted native scrolling via .scrollable class or if -webkit-overflow-scrolling is an inline-style
window.PreventWindowBounce = {
handleEvent: function EventListenerInterface (ev) { if(ev.type in this) this[ev.type](ev); },
bindEvents: function () {
document.addEventListener('touchstart', PreventWindowBounce);
document.addEventListener('touchmove', PreventWindowBounce);
},
/// The code works by checking whether the scroll area is against
/// the container edges and if true prevent touch gesture defaults
/// when the gesture attempts to go off edge.
/// (which would otherwise cause the scroll gesture to scroll parent
/// elements such as the document <body> causing the screen overflow)
allowUp: false,
allowDown: false,
slideBeginY: 0,
touchstart: function(ev) {
var node = this.checkClosest(ev.target);
if(node)
{
this.allowUp = (node.scrollTop > 0);
this.allowDown = (node.scrollTop < node.scrollHeight - node.clientHeight);
this.slideBeginY = ev.pageY;
if(!this.allowUp && !this.allowDown) ev.preventDefault();
}
else ev.preventDefault();
},
touchmove: function(ev) {
if(!this.allowUp && !this.allowDown) return ev.preventDefault();
var node = this.checkClosest(ev.target);
if(node)
{
var up = (ev.pageY > this.slideBeginY);
var down = (ev.pageY < this.slideBeginY);
this.slideBeginY = ev.pageY;
if((up && this.allowUp) || (down && this.allowDown)) return ev.stopPropagation();
}
ev.preventDefault();
},
/// Checks all node parents for elements and whether they are whitelisted
checkClosest: function(node) {
while (node)
{
if(node.nodeType == document.ELEMENT_NODE && (node.style.webkitOverflowScrolling == 'touch' || node.classList.contains('scrollable'))) return node;
node = node.parentNode;
}
return null;
}
};
PreventWindowBounce.bindEvents();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment