Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save searls/0a855d10c634fa07408cbe0673cf4aa4 to your computer and use it in GitHub Desktop.
Save searls/0a855d10c634fa07408cbe0673cf4aa4 to your computer and use it in GitHub Desktop.
/* preventScrollWhenSoftKeyboardAppearsIfThereIsPlentyOfRoom(event)
*
* Attach this handler to `touchstart` on any UI control that brings up the keyboard when you don't want iOS
* MobileSafari to scroll when a user taps it. Assumes that the input is near the top of the page and the user has
* not scrolled down (specific to my case, sorry!)
*
* requires top-level CSS directives so we can add it to the body:
* ```
* .prevent-ios-focus-scrolling {
* position: fixed;
* left: 0;
* right: 0;
* }
* ```
*/
const MAX_KEYBOARD_PROPORTION = .52
const preventScrollWhenSoftKeyboardAppearsIfThereIsPlentyOfRoom = (e) => {
// Bail if not iOS
if (!/iPad|iPhone|iPod/.test(navigator.userAgent)) return
// Bail if there's too little vertical space and scrolling is necessary
if ((e.target.offsetTop + e.target.offsetHeight) / window.innerHeight > MAX_KEYBOARD_PROPORTION) return
// Fix the position of the body momentarily to prevent user agent scrolling
var offset = document.body.scrollTop;
document.body.style.top = (offset * -1) + 'px';
document.body.classList.add('prevent-ios-focus-scrolling');
setTimeout(() => {
// Undo it after 500ms, roughly the amount of time focus animation takes iOS
offset = parseInt(document.body.style.top, 10);
document.body.classList.remove('prevent-ios-focus-scrolling');
document.body.scrollTop = (offset * -1);
}, 500)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment