Prinzhorn / skrollr

Stand-alone parallax scrolling library for mobile (Android + iOS) and desktop. No jQuery. Just plain JavaScript (and some love).
http://prinzhorn.github.io/skrollr/
MIT License
18.53k stars 3.5k forks source link

Skrollr Not working on IOS devices. #265

Open emerg opened 11 years ago

emerg commented 11 years ago

Thanks for developing such an awesome plugin. I'm running into a problem however. I can't seem to get it to work on IOS devices like iphone and ipad. I noticed that your example works just fine on my iphone, so this leads me to believe that there's something wrong with my markup that's causing this. I've tried everything, and I cant quite figure it out. I was wondering if you'd be willing to review this and give me some insight? What am I doing wrong here?

http://monicaanddanny.com/

Thanks so much for the help.

laltaffer commented 11 years ago

I haven't had much of a chance to look into this but I clicked your link and it looks like your timeline content animations (the blocks that come in on the left and right) don't animate all the way in until the top of them touches the top of my viewport. This is all while in Chrome on a Mac Mini. It could be related to that issue as well. I'll try to look into why I'm seeing that behavior later in the day. Hopefully someone else will have time to look too...

emerg commented 11 years ago

Hey, thanks for the feedback. I'm actually aware of the timeline containers not showing until they reach the top of the viewport. That's actually the result of a recent change to the website that I made (scaling down some of page elements at the top of the site) scaling down those elements thus resulted in the need to re-adjust the data variables. Thats just some simple math to fix that. My real issue is basically you cant even scroll the site on an ipad or iphone.. no movement at all. I also tend to get an extra scrollbar within the site. like an additional full page scrollbar right next to the browsers scroll bar, as if there's a div with overflow:scroll;

I dont seem to have any of these issues with skrollrs example, http://prinzhorn.github.io/skrollr/, which leads me to believe there must be something wrong with my markup. I just cant spot it. Any help would be greatly appreciated.

Thanks!

Prinzhorn commented 11 years ago

I don't see a #skrollr-body element

(hint: k not c)

RobertinoValue commented 11 years ago

Yeah, and the extra vertical scrollbar is caused by the wrong height (6902px) being written to the body element. When I change it to <body style="height: auto;"> or <body style="height: initial;"> (in developertools) it is re-calculated by the browser as 6946px. The JS is 44px short somewhere. Probably caused by the changes he made needing a re-calculation, which he mentioned earlier.

emerg commented 11 years ago

Thanks for the help again. I updated the #skrollr-body, but am still having the locked scrolling problem on the ipad. Any other pointers?

Maybe the best solution is to just strip out everything and then add each element in again, to make sure I dont have an extra closing div or something similar. Also, I've integrated this site with wordpress. I don't think that would be causing any issues, but wanted to mention it incase anyone sees an issue with that.

What's the required markup to get scroller set up properly? I dont see a #skrollr-body on http://prinzhorn.github.io/skrollr/ and I was using that as an example.

This is my basic setup right now..

<body>
<div id="skrollr-body">
<div class="example-div" data-XXX="css:stuff;"></div>
</div>
<script type="text/javascript" src="js/skrollr.min.js"></script>
</body>

Is that correct? or am I missing something?

Thanks again, I really appreciate everyone's help.

RobertinoValue commented 11 years ago

skrollr-body is for mobile only, and only when you (also) use other positioning than fixed positioning.

The demo page you're looking at is using fixed positioning exclusively. So it doesn't need the id. And I remember also seeing other positioning in your markup. (Not sure.) When you mix and match positioning (not use fixed positioning exclusively) the id is mandatory for mobile.

From the README.md at https://github.com/Prinzhorn/skrollr :

You just told me it doesn't work on mobile, but why does it? The answer is simple. When using skrollr on mobile you don't actually scroll. When detecting a mobile browser skrollr disables native scrolling and instead listens for touch events and moves the content (more specific the #skrollr-body element) using CSS transforms.

What you need in order to support mobile browsers

Starting with skrollr 0.6.0 there's just one thing you need to do: Include an element on your page with the id skrollr-body. That's the element we move in order to fake scrolling. The only case were you don't need a #skrollr-body is when using position:fixed exlusively. In fact the skrollr website doesn't include a #skrollr-body element. If you need both fixed and non-fixed (i.e. static) elements, put the static ones inside the #skrollr-body element.

From the JavaScript : https://github.com/Prinzhorn/skrollr/blob/master/src/skrollr.js#L260-L272

if(_isMobile) {
    _skrollrBody = document.getElementById('skrollr-body');

    //Detect 3d transform if there's a skrollr-body (only needed for #skrollr-body).
    if(_skrollrBody) {
        _detect3DTransforms();
    }

    _initMobile();
    _updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_MOBILE_CLASS], [NO_SKROLLR_CLASS]);
} else {
    _updateClass(documentElement, [SKROLLR_CLASS, SKROLLR_DESKTOP_CLASS], [NO_SKROLLR_CLASS]);
}
sidonaldson commented 11 years ago

You could always disable mobile mode if you aren't too bothered about a scrollbar and the other enhancements:

        skrollr.init({          
            mobileCheck: function() {
                //hack - forces mobile version to be off
                return false;
            }
        });
linuxdog commented 11 years ago

My page seems to work right - but much to slow (just on iPad / iPhone). Content is still visible after scrolling to next screen and then, second later reacting and invisble. Moving is not working. On Android everything is running fine and as wanted.

Any idea? Is this to much for ios?

cristianocd commented 10 years ago

Any improvement? I can't figure out what's going on here: http://www.xre300rally.com/_/ The background and scrolling get all messed up on iPad. Anyone has experienced something like this?

cristianocd commented 10 years ago

Worked by removing "skrollr-body" and including https://github.com/Prinzhorn/skrollr/blob/master/examples/fixed-positioning.css Also, iOS Safari doesn't background-position, gotta move the background in another way.

ziyan-junaideen commented 10 years ago

I am trying out Skrollr and in mobiles in general, I am not able to scroll. I mean the browser is stuck right on top.

cristianocd commented 10 years ago

1 - Read https://github.com/Prinzhorn/skrollr#what-you-need-in-order-to-support-mobile-browsers 2 - Still stuck? Share your code : bye.

jathayde commented 10 years ago

Okay, so I've tried the fixed-position.css suggestion from @cristianocd (which didn't work since things are positioned in other ways) and have skrollr-body wrapping the scrollable content.

Scrolling works as planned on iPhone and Desktop (and even android phones) but NOT on tablets, neither iPad nor Android (i only have an iPad to test here, but a co-worker reported the Android tablet issue). The site shows the main screen and does not scroll at all (as if the page is locked in place). This behavior is exhibited in landscape and portrait mode on both the actual device and in the iOS Simulator's Safari.

If I implement @sidonaldson 's suggestion, the parallax/scrolling stops working entirely BUT I am able to scroll on an iPad.

The only way I can get the scroll working on iPad is to strike the height attribute from the following code, which then breaks the homepage layout setup (designed to size to the screen as it loads)

#skrollr-body {
  height: 100%;
  position: relative;
  width: 100%;
}

Also, locally I've stripped out all extra javascript, including jQuery and it's subordinates (so there is only Skrollr). in Chrome's emulation, the locked screen only happens when body has a class of skrollr-mobile but it does work fine when it has a class of skrollr-desktop

In the wild: http://www.cargosense.com/

jathayde commented 10 years ago

So apparently, my error was due to the min-height. I set it to a pixel for the tablet (it was already set for the iPhone) and it works. Maybe that helps someone else. argh.

natashavg commented 10 years ago

This from boboroshi helped me as well: #skrollr-body {min-height: 1px;} but for me this was needed for the iPhone.

Jorybraun commented 9 years ago

Ughhh I am having an issue with mobile even though google is lying to me with the dev tools Iphone 4 things are not position right they are stacking on top of each other

www.jorycms2.herokuapp.com

jathayde commented 9 years ago

@jorybraun - no such app at that URL. did you dry the min-height hack? I'd pull up the iOS simulator (inside the xCode bundle) for accurate mobile Safari testing.

Jorybraun commented 9 years ago

jorycms2.herokuapp.com

Jorybraun commented 9 years ago

https://github.com/Jorybraun/personal-website

Jorybraun commented 9 years ago

i put a min height inside the skrollr body , should that be in a media query?

jathayde commented 9 years ago

Yeah. If I recall, I had it in a media query for the Tablet/iPad, but not the phone, so I was having this issue. When I cloned that rule into the iPhone specific media query, it fixed it. We since removed Skrollr due to some jumpiness for certain browsers, so I can't test it right now on our site.

Jorybraun commented 9 years ago

I just put the a media query into the skrollr body

skrollr-body

position: fixed
top: 0
left: 0 
width: 100%
height: auto
@media screen and (min-device-width: 320px)
    min-height: 1% 
@media screen and (min-device-width: 480px)
    min-height: 1%

This just stacked things higher up on top of each other

Jorybraun commented 9 years ago

it seems like the skrollr body isnt actually fixed, as the first div is in place and the rest are below it stacked up, I have my skrollr body inside a fluid-container it might be the issue for mobile, as it seems the body stretches so far down

Jorybraun commented 9 years ago

is there no answer to this problem, im probably missing a previous issue. How ever it appears that every one just turns skrollr off for mobile is there no soloution?

jathayde commented 9 years ago

Jory - All I can say is that I did the 1px hack and it worked for me at the time with the site I was building (which only used Skrollr for parralax on images). The site (which now has the plugin turned off due to browser jumpiness complaints from customers) is www.cargosense.com.

 #skrollr-body {min-height: 1px;} 

I don't know Skrollr that well and if @Prinzhorn has no suggestions, I'd disable it on mobile until you can get his input.

Prinzhorn commented 9 years ago

@Jorybraun do you by any chance have fixed positioned elements inside skrollr-body? If so, read http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/ . skrollr-body is moved using CSS transforms.

Jorybraun commented 9 years ago

yeah so skrollr-body is fixed, everything else is absolute

Prinzhorn commented 9 years ago

As far as I understand your layout, you don't need skrollr-body. Nothing actually scrolls. You should re-read https://github.com/Prinzhorn/skrollr#what-you-need-in-order-to-support-mobile-browsers

ldiaz commented 9 years ago

Hi, maybe have you checked http://squarespace.com/seven/interface, somehow they have manage to have some elements with relative position and some with fixed position within the skrollr-body for the mobile version.

maurocolella commented 9 years ago

While using the HTML boilerplate, I faced the same issue. An absolute positioned element, with a z-index and a specified height, would apparently collapse to a null height when used with skrollr on mobiles. Hence: nothing more to scroll in my viewport. I would be stuck at the top.

The absolute positioned element was a nested child of #skrollr-body

I had to remove the class "clearfix" from that element in order to resolve the issue.

/*
* Clearfix: contain floats
*
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* `contenteditable` attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that receive the `clearfix` class.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.clearfix:before,
.clearfix:after {
    content: " "; /* 1 */
    display: table; /* 2 */
}
.clearfix:after {
    clear: both;
}

However, the bug appears on both Google's Blink, and plain vanilla Webkit on iOS. Given the variety of reported "cases", and the fact that a few of them involve setting a default height for the #skrollr-body, or a similar modification, I suspect it has something to do with the way skrollr handles heights in mobile mode.

Prinzhorn commented 9 years ago

@maurocolella have you tried the very latest version (>= 0.6.28)?

maurocolella commented 9 years ago

Yes @Prinzhorn. And thank you for the lib, it's really nice. I am using version 0.6.29.

Prinzhorn commented 9 years ago

It would be great if one of you could create a very simple demo page which makes this reproducible.

maurocolella commented 9 years ago

I'll try when I am done.

On Sat, Nov 22, 2014 at 8:13 PM, Alexander Prinzhorn < notifications@github.com> wrote:

It would be great if one of you could create a very simple demo page which makes this reproducible.

— Reply to this email directly or view it on GitHub https://github.com/Prinzhorn/skrollr/issues/265#issuecomment-64078351.

isaacalves commented 9 years ago

I'm using skrollr on a page that has only fixed positioned elements, and it works well on desktop, iOS and Android devices. Except for one thing - I have a function that shows/hides a fixed navbar, and it is called upon the scroll event, defined on the (jQuery wrapped) window element. It works normally on desktop, but on iOS and Android devices, the scroll event doesn't fire (and the navbar remains always visible).

ps: I don't have the "skrollr-body" id on the body element. As far as I know I don't need that if I only have positioned elements. I tried that anyway, but then the page turns blank on Android.

Prinzhorn commented 9 years ago

but on iOS and Android devices, the scroll event doesn't fire

Use skrollr's render event https://github.com/Prinzhorn/skrollr#render

isaacalves commented 9 years ago

thank you!

colin-johnson commented 9 years ago

Hey, thanks for the plugin, it's working great on the desktop version of my site, but I'm having problems on mobile. I've included the #skrollr-body tag to contain all the content that needs to scroll on mobile. But when viewing the site on mobile it just scrolls from the top of the site all the way to the bottom, and vice versa, and keeps repeating this.

View it live on a mobile device here: http://ai.risingsenior.vdsla.com/

Could you please help me find a solution to this? This project is due in a day or two and would greatly appreciate a descriptive solution to this problem

flyarrowplane commented 9 years ago

My site has a navigation situation similar to the fixed_nav.html example that comes with skrollr. When it said "desktop only!" I guess I was assuming that this meant not on mobile... but that it could still work on an iPad horizontally, which is typically a desktop-sized layout. I get now that this isn't the case and, generally, why.

I now have a div with #skrollr_body surrounding my content, as in the fixed_nav.html example, which makes the page scrollable... but the skrollr effect is gone, which is a bummer. Definitely would be nice if there is a way to have this working.

stevenheijtel commented 9 years ago

Here the same problem in some occasions, reason is Skrollr calculates the height of the page before all images are loaded. Moving skrollr.init() to window.load does the trick for me:

/* jQuery */
jQuery(window).load(function($) {
  var s = skrollr.init();
});