Skip to content

Instantly share code, notes, and snippets.

@leereamsnyder
Last active May 27, 2016 19:38
Show Gist options
  • Save leereamsnyder/33504ae18b58d25646b6 to your computer and use it in GitHub Desktop.
Save leereamsnyder/33504ae18b58d25646b6 to your computer and use it in GitHub Desktop.
Restore window.scrollTo in iOS Safari after tapping the status bar
/**
**UPDATE**: This was fixed in iOS 8. But this could still be valid for iOS 7 and below.
I believe this was first noticed here: http://blog.b123400.net/window-scrollto-and-ios-status-bar/
> When the status bar is tapped, the page scrolls to the top and url bar is shown,
> then window.scrollTo doesn't work anymore.
Yep!
In the same post, Mr. b123400 notes:
> To re-enable it, either:
>
> 1. User scrolls the page, or
> 2. Trigger window.scrollTo by user interaction, such as click and touchend
This is my attempt to do #2 automatically, which should 'fix' window.scrollTo elsewhere
Started talking about it here:
https://github.com/julianshapiro/velocity/issues/282
TODO:
- remove the jQuery dependency? nothing too tricky here.
- better user agent sniff? I already don't do this for iOS Chrome... how about Opera?
*/
;(function ($, window, document, undefined) {
'use strict';
// Bail if not iOS or is iOS Chrome
// https://developer.chrome.com/multidevice/user-agent
if ( ! /iPhone|iPad|iPod/.test(navigator.userAgent) || navigator.userAgent.indexOf('CriOS') > -1 ) { return; }
// thx: http://davidwalsh.name/javascript-debounce-function
var debounce = function(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
timeout = null;
func.apply(context, args);
}, wait);
};
};
var checkAndAddTouchEvent = debounce( function() {
if ( $(window).scrollTop() !== 0 ) { return; }
$(document).one('touchstart', function() {
/*
This is the magic bit: calling window.scrollTo in a touchend/touchstart/click handler
seems to break iOS Safari out of its "na-na-not-listening!" funk
touchstart seems like the way to go
That's my big assumption here: someone will probably touch *something*
before you have to fire window.scrollTo
we're already at the top, so in theory scrollTo(0,0) this should have no effect
other than allowing window.scrollTo to work elsewhere
UPDATE: window.scrollBy also works, so that's even less likely to cause trouble
*/
window.scrollBy(0,0);
});
}, 500 ); // 500ms seems like enough time
$(window).on('scroll', checkAndAddTouchEvent);
}(jQuery, this, this.document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment