I solved it, thank god. Only about 20 hrs spent on this, but at least it works now...
The instructions on the iScroll site are incomplete, and don't truly work with jQM, so here's what I had to do.
First, the HTML for the scrollable section needed to look like the below, which is as it's described in the documentation:
- <div data-role="content" id="wrapper" class="scrollable">
- <div name="msg_holder" id="msg_holder"> <!-- scroller element -->
- <!-- dynamic data loaded in here -->
- </div>
- </div>
I also added the iScroll stuff inline within the <div> at the bottom (below the HTML), also described in the documentation (the other event-based triggering looked like it was going to be difficult with jQM):
- <script type="text/javascript">
- var myScroll = new iScroll('wrapper');
- </script>
Second, I needed to have a CSS class definition that matched the scrollable class, like the below. This is not clearly specified anywhere that I could find, found it on digging around in forums, so YMMV.
- .scrollable {
- position: absolute;
- top: 50px;
- left: 0;
- right: 0;
- bottom: 0;
- overflow: scroll;
- }
Next, since I'm dynamically creating the content, I had to do some tricks. It's basically a list of elements that I iterate over when I get it back as JSON and then put it into the HTML. To this, I added at the very bottom an empty <div> that acted as my "last" element below the list, all within the pagebeforeshow event of that page:
- <div id="scroll_place_holder"></div>
JS to make it work:
- $('#message_page').live("pageshow",function(event, data) {
- setTimeout(function () {
- myScroll.refresh();
- myScroll.scrollToElement("#scroll_place_holder", 0);
- }, 0);
- });
Important note on this structure: I originally had the myScroll.refresh() within the pagebeforeshow, but what wound up happening is that I had to set the setTimeout to times greater than 0 (500 seemed the minimum), or else it wouldn't work, presumably because jQM wasn't done adding the elements when it was called. I was also concerned that this would get worse as the number of items went up. Therefore I put the refresh in a later event (pageshow) to be sure that everything was done, and there it was fine with a 0. Unfortunately this creates a small amount of jumpiness, but it's minor in my opinion.
Lastly, since I have a fixed footer that was taking up space, I had to give this <div> some height so that the content would actually appear above the footer. This is variable based on what your footer is, but mine turned out like below:
- #scroll_place_holder {
- height:70px;
- }
After all the hassle of getting this to work, I can say that the result is actually rather nice - truly fixed headers/footers on my page, and it resolved an issue I had reported where my footer was floating above the keyboard.
Probably worth noting too that all of this was running jQM 1.0.1, jQuery 1.6.4, iScroll 4, PhoneGap 1.4 on iOS 5.1 (iPhone 4S).