jquery-archive / jquery-mobile

jQuery Mobile Framework
https://jquerymobile.com
Other
9.7k stars 2.41k forks source link

Jumpy and blinky page transitions #455

Closed woutervanwijk closed 12 years ago

woutervanwijk commented 13 years ago

As of A3, page transitions are still not smooth on many platforms so this issue is being used to track our progress on improving the situation. This is a multi-faceted issue because we need a smooth transition system that works across all our target platforms and maintains all the normal "web" behavior such as returning a user back to their original scroll position when re-visiting page.

This issue originally started out regarding the address bar on iOS and flashes on Android but has expanded to discuss our progress on the larger re-write that Jesse, Kin and Scott have been working on so I've added this intro and revised the title accordingly. All transition-related issues will be closed and push back into this issue so we can track them together. A solution to the symptoms seen will require a deep re-factor and re-approach so it makes sense to look at this issue holistically and any fix for one platform needs to be evaluated against it's impact on another.

In iOS, there is a noticeable blink of the un-rendered page (checkboards) while the page scrolls down to a previous anchor position, among other situations. On newer builds of Android, there is flash of the previous page when executing a transition.

Also, when using long pages Safari on an iPhone 3GS, the address bar jumps up and down after page transitions. Not always, but it sometimes does (especially when selecting the items at the bottom of the listview).

Safari probably figures that because of the hash-change, the address bar needs to be visible. It will hide it again. Because of that, the user experience is not great. In jQtouch, the hash doesn't change, and Safari doesn't show this behaviour.

Maybe it would be considered an Apple-bug, but for me it's quite an issue, and for others too:

http://forum.jquery.com/topic/iphone-safari-address-bar-jumps-down-after-page-transition

I really like jq mobile, so it would be great if it could be fixed in some way.

fabriziogiordano commented 13 years ago

might be considerd to implement the trick used in http://www.20thingsilearned.com/js/twentythings.history.js

They used: history.pushState [ https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history ]

I do not know if webkit for iphone safari support that.

BTW at least is it possible to edit the hash tag from # to #! to be google search compliant?

Thanks Fabrizio

speedmax commented 13 years ago

+1

This is very annoying

schorsch commented 13 years ago

+1

really annoying

Vincentgr commented 13 years ago

+1 Again. Ridiculously annoying when transitioning between pages.

bradya commented 13 years ago

+1 from me also

brandonaaskov commented 13 years ago

+1

brandonaaskov commented 13 years ago

Not sure if this falls in line with this issue, or issue 568 (https://github.com/jquery/jquery-mobile/issues#issue/568), but from what I can tell, it's a matter of going from a page that isn't longer than the viewport's height to a page that is. In the first page, you'll see the address bar, and after changing the page, you'll see the page jump to hide the address bar.

To workaround this for now, you can dynamically set the min-height of .ui-page to whatever the device size is, but I'm still trying to find out how to determine what that device size is (I tested it just by hard-coding a value for the iPhone Simulator). Ideally (at least for my case), when the page is rendered, if the page is less than the device's height, this would happen automatically.

Scott/Todd, if the community agrees on this approach of setting the min-height to the height of the device (or the height of the viewport plus any status/nav bars), we can tackle that here at Brightcove.

scottjehl commented 13 years ago

Believe me, big +1 from the team on this one too :)

I did some testing and found it's not related to updating the hash, setting focus to the first focusable element, or calling silentScroll... so hopefully Brandon is on to something!

Brandon, can you send a pull request with that workaround? I'll be very happy to take a look!

brandonaaskov commented 13 years ago

Hi Scott,

Is there some way to get the device's height? I've looked around and haven't turned up anything yet.

scottjehl commented 13 years ago

hmm.. screen.availHeight ?

brandonaaskov commented 13 years ago

So, there seem to be two good ways to go about doing this.

If you're loading in jQuery Mobile stuff the way I am since I'm in dev (by pointing the js directory), then you can just call this at any point in your code: $('.ui-page').css('minHeight', screen.availHeight); Here I'm just applying a min-height to all of the .ui-page elements and setting it to the device's screen height.

However, the better way (I say better since it's documented already to work this way) is to modify the jQuery Mobile defaults, like so: $(document).bind("mobileinit", function(){ $.extend($.mobile, { metaViewportContent: "width=device-width, height=device-height, minimum-scale=1, maximum-scale=1" }); });

Here I'm just adding the height value, which is not there by default.

This is working for me in keeping my page transitions from "jumping", but I'm curious to see if this works for others as well.

Since that has to happen after jQuery gets loaded, but before jQuery Mobile gets loaded, I had to change my setup a bit to get it to work. Based on that setup, users would be required to have jQuery separate from jQuery Mobile, which is not currently how the ant build process is setup, but perhaps that is the plan for the first release (similar to jQuery UI).

Alternatively, if we find that a lot of people are looking to use this option, maybe we can just make it one of the defaults? Time will tell, I suppose.

woutervanwijk commented 13 years ago

I tried the second option and it works well. Thanks! Are there any drwabacks in making it one of the defaults? If not, I suppose it should be a default, otherwise it would confuse new developers imho.

scottjehl commented 13 years ago

Nice work! If this fixes the issue and doesn't interfere with taller pages ( as in, it acts as a min height), then let's roll it into the defaults.

scottjehl commented 13 years ago

We'll do some testing on all the devices here but my initial testing shows this fixes the address bar issue. Look for the commit soon! Thanks again.

patussay commented 13 years ago

The metaViewportContent solution is perfect but another problem arises when you decide to change the orientation of your device on the fly (at least for me), it doesn't dynamically change the size of the viewport, which apparently remains stuck on the old orientation value. You need to refresh the page to get the right view and so on.

Otherwise it's a big step forward since this visual problem does not seem so easy to resolve. By the way many thanks to the team for the great work they have already done.

tested with the latest rev.jqm + ipod 4g ios421

scottjehl commented 13 years ago

ahh rats! Yeah, that's a pretty big problem actually. There are so many finicky issues with orientation change in iOS. I reported the issue to Apple where the layout zooms in on change when user-scaling is enabled, but so far they haven't released a fix for that one either. We may need to look into setting a min-height on certain elements through CSS. Maybe the body element will work...?

patussay commented 13 years ago

CSS would be good but i think it's really a job for Mr javascript.

A quick 'console.log' test reveal that the event.orientation in jqm (circa line 389 w/o jq144) is never updated (iOS_421) and keeps the value "portrait" (if you start browsing in portrait) even if you flip your device to landscape.

On the other hand if you start browsing in landscape mode, the value is correct the 1st time but lost afterwards and cannot be recovered (until you reload your page), the fact is that the className is never correct unless you keep your device in one orientation from the start.

update: if you keep the original metaViewportContent from JQM (w/o "height=device-height" as mentionned above), the event.orientation is correct in mobile safari. Strange isn't it !

patussay commented 13 years ago

As a starting point, here is a solution for the address bar, it's not perfect and beware not to mix this solution with the jumping page issue that still must be adressed (and going to be a hard case). Test it first without scrolling, it acts as the silentScroll should work, if you change orientation of your device everything is fine.

Of course, pages are intended to be scrolled and many unpleasant display issue appear if you act upon a link and you are somewhere in your page (perhaps some kind of default browser behaviour mixed with the lastScroll data sent to silentScroll() + loading of the page + ...? = it's a lot to take care in a short time). The problem also appears when the page is in cache but the effect is less visible.

But 'back to our sheeps'.

Here's what i did, i worked from the solution 1 of brandon (as it seems impossible to mix device-width and device-height with iOS, as said above, the orientation is not updated) :

if(event.orientation) {
* in line 390 of jqm (standalone version without jq.144)
    [change] 
        $html.removeClass( "portrait landscape" ).addClass( event.orientation );
    [for]
        $html.removeClass( "portrait landscape" ).addClass( event.orientation ).css({'min-height': screen.availHeight});

* i also added beneath it a setTimeout, sometime the address bar show up especially when you change your orientation
        setTimeout(function() { window.scrollTo(0, 1); }, 20);//could be connected with silentScroll ?
}//end event.orientation

* need to add few lines at the beginning of your css file, otherwise the page is truncated during animation
        html {
            position:relative;
        }

UPDATE
Forget about the above block of code as the css rule creates problem on Safari:desktop (doesn't like position:relative in this situation), but for testing purpose, put this in your jqm.js file

if(event.orientation) {
    //use class for every browser
    $html.removeClass( "portrait landscape" ).addClass( event.orientation );

    //only mobile
    if($.support.touch) {
        $html.css({minHeight: screen.availHeight, position: 'relative'});
        setTimeout(function() { window.scrollTo(0, 1); }, 20);
    }
}

Tested only on iOS4.

brandonaaskov commented 13 years ago

In jquery.mobile.event.js in the special_event.orientation function elem.clientWidth and elem.clientHeight only report correctly the first time the screen renders. Once it rotates, they report the device's height and width.

Then, I tried taking out width=device-width, height=device-height from the metaViewportContent default (jquery.mobile.core.js) altogether and everything seems to be working wonderfully, including rotation. patussay, can you give that a shot and see if it works for you?

patussay commented 13 years ago

The bare minimum for iOS (and maybe other mob-systems) seems to be the following rule

metaViewportContent: "initial-scale=1, maximum-scale=1",

and it acts just like the default one in JQM

metaViewportContent: "width=device-width, minimum-scale=1, maximum-scale=1",

But what about the url bar ? my attempt was to hide it from the view and the following metaviewport rule fails to do so, (I must admit that it's a pity that your 2nd solution fails because of the orientation, it would have been perfect and would have spared a lot of time and energy for such a thing that's normally done with a setTimeout).

This does not work because the address bar is always visible, or did i miss something with your explanation ?

mesca commented 13 years ago

To get the real visible height/weight, I use something like:

window.onorientationchange = function() {
    h = window.innerHeight ? window.innerHeight : $(window).height();
    w = window.innerWidth ? window.innerWidth : $(window).width();
    // Call your resize function
    // update_orientation();
}
$(window).trigger('onorientationchange');

It will report the correct width and height for the visible part of the viewport. Works well in any orientation and also in full screen mode. Then, in update_orientation(), you can detect the height of the page and adjust it if less than the reported height.

urlsangel commented 13 years ago

This is a big issue for the team here too.

Will there be a fix for this in the next release? If not, any idea when this will be looked at?

speedmax commented 13 years ago

Same here, Any update on this issue?

It will have huge impact on user experience

fabriziogiordano commented 13 years ago

do you think we can get some clues or inspirations from the way this webapp is managing the URL. They change the hash without triggering the navbar appear.

http://m.untappd.com

[ i'm not affiliated or related to untappd ]

avibha commented 13 years ago

+1

jstreb commented 13 years ago

I just took a look at http://m.untapped.com and for me the address bar always appears when the hash changes. Are you seeing something different? For example if I am on the pub tab, scroll down the page and then click on one of the pubs the page jumps back and shows the address bar. Is this different behavior then what you are seeing?

scottjehl commented 13 years ago

So Todd and I were just chatting about this and here's what we're thinking:

The address bar showing and hiding doesn't often cause much of a problem in regards to transition smoothness. For example, if you go to the homepage of jQuery Mobile docs, and click the first link, the transition is quite good on iOS. Yeah, the address bar shows, but it's smooth overall and the transition works as you'd expect.

The real problem occurs when you scroll down the page and then click a link. Ideally, the transition would occur from the existing scrollTop to the correct scrollTop of the page you're transitioning to (which is saved in data when a page has already been visited). Unfortunately, this is the part that doesn't work quite right, but I think it's the fault of our own sequence of events (and not a browser issue).

Maybe we should first direct our efforts there, since it's clearly a problem that we can solve. You can test this in Chrome as well; just scroll far down a page and click any link. The transition will blink rather than working properly.

jstreb commented 13 years ago

Yes, I think there are a handful of issues here.

  1. if a page's height does not take up more then a 100% of the window then after the transition the page shifts down because the silent scroll will not hide the address bar on the shorter page. ( I just pushed a pull request to address this. )
  2. If a user scrolls down the page, clicks on a link to navigate to a new page, then the transition does not look right. This seems to be a new issue, specific to HEAD. The alpha 2 branch seems to do this correctly.
  3. As Scott and Todd mentioned returning to page that you had previously scrolled down on jumps to the bottom of the page after the transition. Ideally there would be no jump but rather you would just slide over to the previous scrollTop.
  4. You will always see the address bar appear because an a href was clicked. As Scott and Todd mentioned this seems like the right thing.

Anyway, I will start looking into the suggestion that Todd and Scott have made about transitioning to the existing scrollTop.

scottjehl commented 13 years ago

Awesome - sounds like we're on track now. Thanks Jesse

jstreb commented 13 years ago

Hi all,

I pushed up a fix to make the pages not jump around during the transitions. We looked into scrolling from where we were in the page to the new page, but there are too many performance problems for this to work well. What we see now is similar to alpha2 where we scroll up to the top of the page and then scroll over.

New to this update is that the page does not go down and then back up during the transitions, which is what the original bug was. If the user hits back we will take them back to the page and then scroll them to where they were in the page. (known issues is that on iOS the scroll down to where they previously were can result in seeing some flicker.)

Please let us know if this improves the jumpiness of the transitions.

toddparker commented 13 years ago

Jesse's fixes make this look much better. I'm keeping this issue as high because he's working on even more refinements but it's no longer a blocker.

scottjehl commented 13 years ago

Nice work, Jesse. One thing I noticed, and I'm not sure if it's related: in Safari (desktop), the scroll height is much taller than the page itself. Maybe it's related to the 120% height thing? Doesn't seem to show up on iOS.

toddparker commented 13 years ago

After doing more testing, the page blink that happens is still pretty bad so we need to keep working on this before it's not a blocker.

clarkni5 commented 13 years ago

Here is my suggestion for improving sliding transitions. I think this is relevant to issue 3 that Jesse mentioned on Jan 25th. http://forum.jquery.com/topic/improving-page-transitions

The basic idea is to put a blank page in-between the transition from page A to page B. If you perform the scroll on the blank page, the user will never see the content jump around and the transition should look pretty smooth.

BMCouto commented 13 years ago

I would really need to see this solved in order to use it in my upcoming projects.

toddparker commented 13 years ago

Transitions cause a blink of the previous page on newer builds of Android. We have been known this was an issue since A3 but I want to link up this newer issue #1124 that provides more detail on the Android situation. I will be closing 1124 so we can just track all transition work under this issue. https://github.com/jquery/jquery-mobile/issues/1124

Thread on the forum is also has useful ideas and commentary: http://forum.jquery.com/topic/page-transitions-are-still-blinky-on-android-2-2-2-3-jqmobile-a3#14737000002041003

speedmax commented 13 years ago

The page transition still "blinks" badly on jquery mobile A4 release on Android 2.2

toddparker commented 13 years ago

We were working on trying to land some transition fixes for A4 but we just didn't get there in time so they are actually the same as A3. This is a going to be a big focus for us in the next few weeks so beta should be a lot smoother.

cmsfruit commented 13 years ago

I too, am experiencing this issue with JQM a4 and iOS

brianantonelli commented 13 years ago

I'm seeing this on JQM a4/iOS when navigating to a static page. This only happens on a single page and only the first time its rendered. Going back to it (data gets updated via DOM) never shows the flash again. I'm running this inside of a uiwebview so I know its not an issue with the safari toolbar.

badtoto commented 13 years ago

+1 hope it will be fixed in beta :)

wpccolorblind commented 13 years ago

seeing this as well on a4.1 + droid x

abdlquadri commented 13 years ago

Hi all, Good work here. I hope this sorted out soon. Keep up.

jblas commented 13 years ago

Hi,

I will be out of the office the rest of this week, returning on Monday, May 2nd. I will not be responding to email during this period.

Kin Blas Adobe Systems, Inc.

ha17 commented 12 years ago

@brandonaaskov's fix worked for me when it was flickering in iOS 4.3 on the iPad:

$(document).bind("mobileinit", function(){ $.extend($.mobile, { metaViewportContent: "width=device-width, height=device-height, minimum-scale=1, maximum-scale=1" }); });

Still flickers on a flip but not on a normal slide, etc. I'm using A4.1

tbosch commented 12 years ago

Hello, just created a solution for android (see the above pull request).

For this I did the following: 1.) add a -webkit-transform:translate3d(0,0,0); to the body of the page. This fixes the white flickers at the start/end of the animations.

2.) reimplemented the animations using css3 transitions instead of css3 animations. This fixes the problem that the old page shows up for a moment at the end of page transitions.

I also implemented a test for android browsers, so on iOS or other devices nothing changes.

What do you thing about this? Tobias Bosch

sherkal commented 12 years ago

Cant believe this isnt fixed in the lastest build yet..

toddparker commented 12 years ago

@sherkal - It's a pretty complex problem to solve and we needed to do a lot of re-org and re-factoring to the page scripts first before we could try to finesse the transition smoothness. Once we get beta 1 out, this is one of the big ticket items for beta 2.

scottjehl commented 12 years ago

We've spent the last few days on transitions and just landed the best we've got in master. The address bar rarely shows up (in iOS at least), and blinks are mostly gone. Please test and let us know if you see any issues! Thanks

speedmax commented 12 years ago

Awesome, you are the man.. Where are you located I want to buy you a beer :)