Created
January 19, 2018 14:24
-
-
Save Martin-Pitt/86930b109c3d24130f67d8bb14eea867 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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