As it turns out double tapping the native status bar will trigger a scroll event on document.body
which you can in fact listen for. Trick is, as you mentioned, how can you determine if it's from a double tap or not?
In order to detect it, the body has to be scrolled down to begin with. And setting the scroll position causes a scroll event.
While it's a bunch of hacks, I've been able to get this working:
Code: https://github.com/HenrikJoreteg/holy-grail-ios-layout
Demo: http://ios-layout.surge.sh
Basically, you don't really use the <body>
as a container. You set it as position: absolute
and full height/width. Then you have some kind of container element that you set to position: fixed
that you use as your actual container for your content.
Doing this lets you programmatically scroll the body without affecting anything visual on the page at all.
Now you're set up to listen for scroll events on the body and ideally the user can't actually cause a scroll on the body except via double tapping the status bar.
Unfortunately you have to do all sorts of silly things to make this work.
- Put something taller than
100%
in the body so the body can actually has something to scroll. - Programmatically set the scroll position to 1 to start and after each status bar double tap.
- Set a debounced scroll handler on the body that only fires if it knows the event wasn't caused by setting the position to 1.
- As it turns out, iOS also likes to break thing when you rotate the phone, etc.
- Use the following CSS to make the contents of your actual content containers scrollable with momentum and rubber-banding:
overflow-y: scroll; /* has to be scroll, not auto */
-webkit-overflow-scrolling: touch;
Anyway, it's something :)
More info in the github repo, but anyway, this really does seem to work quite well for iOS 8 (haven't tested other versions of iOS).