From 054a665158b1be17d16f3ad8397b1042da56a222 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Sat, 28 Apr 2018 16:37:55 -0700 Subject: [PATCH] prevent scroll bouncing on iOS --- index.html | 3 +- js/lib/inobounce.js | 131 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 js/lib/inobounce.js diff --git a/index.html b/index.html index a0cee82..50f4b6e 100644 --- a/index.html +++ b/index.html @@ -214,6 +214,7 @@ Good luck, and thanks again! + @@ -1679,4 +1680,4 @@ Thank you so, so much for doing this again, wow. Finally, go to "translations.txt" and follow the instructions there, in order to let this game "know" your translation exists. ---> \ No newline at end of file +--> diff --git a/js/lib/inobounce.js b/js/lib/inobounce.js new file mode 100644 index 0000000..2e5d5f5 --- /dev/null +++ b/js/lib/inobounce.js @@ -0,0 +1,131 @@ +/*! iNoBounce - v0.1.6 +* https://github.com/lazd/iNoBounce/ +* Copyright (c) 2013 Larry Davis ; Licensed BSD */ +(function(global) { + // Stores the Y position where the touch started + var startY = 0; + + // Store enabled status + var enabled = false; + + var supportsPassiveOption = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function() { + supportsPassiveOption = true; + } + }); + window.addEventListener('test', null, opts); + } catch (e) {} + + var handleTouchmove = function(evt) { + // Get the element that was scrolled upon + var el = evt.target; + + // Check all parent elements for scrollability + while (el !== document.body && el !== document) { + // Get some style properties + var style = window.getComputedStyle(el); + + if (!style) { + // If we've encountered an element we can't compute the style for, get out + break; + } + + // Ignore range input element + if (el.nodeName === 'INPUT' && el.getAttribute('type') === 'range') { + return; + } + + var scrolling = style.getPropertyValue('-webkit-overflow-scrolling'); + var overflowY = style.getPropertyValue('overflow-y'); + var height = parseInt(style.getPropertyValue('height'), 10); + + // Determine if the element should scroll + var isScrollable = scrolling === 'touch' && (overflowY === 'auto' || overflowY === 'scroll'); + var canScroll = el.scrollHeight > el.offsetHeight; + + if (isScrollable && canScroll) { + // Get the current Y position of the touch + var curY = evt.touches ? evt.touches[0].screenY : evt.screenY; + + // Determine if the user is trying to scroll past the top or bottom + // In this case, the window will bounce, so we have to prevent scrolling completely + var isAtTop = (startY <= curY && el.scrollTop === 0); + var isAtBottom = (startY >= curY && el.scrollHeight - el.scrollTop === height); + + // Stop a bounce bug when at the bottom or top of the scrollable element + if (isAtTop || isAtBottom) { + evt.preventDefault(); + } + + // No need to continue up the DOM, we've done our job + return; + } + + // Test the next parent + el = el.parentNode; + } + + // Stop the bouncing -- no parents are scrollable + evt.preventDefault(); + }; + + var handleTouchstart = function(evt) { + // Store the first Y position of the touch + startY = evt.touches ? evt.touches[0].screenY : evt.screenY; + }; + + var enable = function() { + // Listen to a couple key touch events + window.addEventListener('touchstart', handleTouchstart, supportsPassiveOption ? { passive : false } : false); + window.addEventListener('touchmove', handleTouchmove, supportsPassiveOption ? { passive : false } : false); + enabled = true; + }; + + var disable = function() { + // Stop listening + window.removeEventListener('touchstart', handleTouchstart, false); + window.removeEventListener('touchmove', handleTouchmove, false); + enabled = false; + }; + + var isEnabled = function() { + return enabled; + }; + + // Enable by default if the browser supports -webkit-overflow-scrolling + // Test this by setting the property with JavaScript on an element that exists in the DOM + // Then, see if the property is reflected in the computed style + var testDiv = document.createElement('div'); + document.documentElement.appendChild(testDiv); + testDiv.style.WebkitOverflowScrolling = 'touch'; + var scrollSupport = 'getComputedStyle' in window && window.getComputedStyle(testDiv)['-webkit-overflow-scrolling'] === 'touch'; + document.documentElement.removeChild(testDiv); + + if (scrollSupport) { + enable(); + } + + // A module to support enabling/disabling iNoBounce + var iNoBounce = { + enable: enable, + disable: disable, + isEnabled: isEnabled + }; + + if (typeof module !== 'undefined' && module.exports) { + // Node.js Support + module.exports = iNoBounce; + } + if (typeof global.define === 'function') { + // AMD Support + (function(define) { + define('iNoBounce', [], function() { return iNoBounce; }); + }(global.define)); + } + else { + // Browser support + global.iNoBounce = iNoBounce; + } +}(this));