orientationchange event returns wrong values on Android #793

Closed
jaybuys opened this Issue Jan 12, 2011 · 13 comments

Comments

Projects
None yet
9 participants
@jaybuys

jaybuys commented Jan 12, 2011

I'm trying to create a little mobile site and need to adjust a few minor layout things based on the screen orientation. While messing around with the orientationchange function I think I've uncovered a bug on Android devices.

When the orientationchange event fires Android appears to return the wrong orientation. I.e. when the screen is horizontal it returns "portrait" when it should be returning "landscape" and vice-versa.

I tested on an original Motorola Droid and an HTC Incredible and they both behave the same way. A commenter on my jQuery forum post confirms HTC Desire is incorrect as well. iPod/iPhone devices appear to return the proper values without a problem.

I tried using the event value and also checking for the CSS .portrait and .landscape classes and it's the same either way.

I have a demo page you can view online here:
http://temp.thisisvisceral.com/orientation-test.html

My forum post with code attached is here:
http://forum.jquery.com/topic/orientationchange-event-returns-wrong-values-on-android

@jzaefferer

This comment has been minimized.

Show comment
Hide comment
@jzaefferer

jzaefferer Jan 12, 2011

Member

I've seen that issue on a project as well, and found that the event is triggered too early. You can verify that by putting in some rather long timeout, e.g. 500 milliseonds. A workaround would check if the orientation actually changed, and delay triggering the event until it does.

Member

jzaefferer commented Jan 12, 2011

I've seen that issue on a project as well, and found that the event is triggered too early. You can verify that by putting in some rather long timeout, e.g. 500 milliseonds. A workaround would check if the orientation actually changed, and delay triggering the event until it does.

@MartinMa

This comment has been minimized.

Show comment
Hide comment
@MartinMa

MartinMa Jan 14, 2011

Is this issue linked to a specific Android version? Because the orientationchange event isn't fired at all on the LG GT540 (Android 2.1) - used your demo page. I assumed that jQuery Mobile emulates this event when it is not natively supported?

Should I use the resize-event instead and check the window's height and width by myself for now? Does the resize event fire too early, too?

Is this issue linked to a specific Android version? Because the orientationchange event isn't fired at all on the LG GT540 (Android 2.1) - used your demo page. I assumed that jQuery Mobile emulates this event when it is not natively supported?

Should I use the resize-event instead and check the window's height and width by myself for now? Does the resize event fire too early, too?

@depeele

This comment has been minimized.

Show comment
Hide comment
@depeele

depeele Jan 18, 2011

Contributor

The 'orientationchange' event does not report the proper value for several devices that we've tested -- the Nexus One, Droid in particular.

These devices seem to trigger an 'orientationchange' event before the window is resized to reflect the new orientation.

The existing orientation handling code will report the exact opposite orientation after the initial 'orientationchange'.

I've submitted a pull request that addresses this issue. The pull fixes this by creating two separate orientation handlers -- one for browsers that natively support orientation and a second that basically uses the current code.

If the browser has native orientation support, then map between device-specific orientation values (in degrees) and a more easily used textual value (i.e. 'portrait', 'landscape'). The mapping is based upon an initial, baseline measure of the window ratio compared to the reported orientation which is performed once the DOM is reported ready and the window size measure can be trusted.

If there is not native orientation support in the browser, fall back to a window ratio measure initiated on window resize.

Contributor

depeele commented Jan 18, 2011

The 'orientationchange' event does not report the proper value for several devices that we've tested -- the Nexus One, Droid in particular.

These devices seem to trigger an 'orientationchange' event before the window is resized to reflect the new orientation.

The existing orientation handling code will report the exact opposite orientation after the initial 'orientationchange'.

I've submitted a pull request that addresses this issue. The pull fixes this by creating two separate orientation handlers -- one for browsers that natively support orientation and a second that basically uses the current code.

If the browser has native orientation support, then map between device-specific orientation values (in degrees) and a more easily used textual value (i.e. 'portrait', 'landscape'). The mapping is based upon an initial, baseline measure of the window ratio compared to the reported orientation which is performed once the DOM is reported ready and the window size measure can be trusted.

If there is not native orientation support in the browser, fall back to a window ratio measure initiated on window resize.

@TZAdvantage

This comment has been minimized.

Show comment
Hide comment
@TZAdvantage

TZAdvantage Feb 1, 2011

@depeele, i added some comments to your commit here depeele@798a711#commitcomment-257748

@depeele, i added some comments to your commit here depeele@798a711#commitcomment-257748

tbosch pushed a commit to tbosch/jquery-mobile that referenced this issue Jul 5, 2011

@tunylund

This comment has been minimized.

Show comment
Hide comment
@tunylund

tunylund Sep 5, 2011

What is the status with this one? The original pull request was closed due to too complex diff output. Was a new one ever created? The issue still exists in jquerymobile beta 2.

tunylund commented Sep 5, 2011

What is the status with this one? The original pull request was closed due to too complex diff output. Was a new one ever created? The issue still exists in jquerymobile beta 2.

@ghost ghost assigned johnbender Sep 6, 2011

@denchev

This comment has been minimized.

Show comment
Hide comment
@denchev

denchev Sep 12, 2011

Yes, setting "orientation" to false fixes the problem. jQuery Mobile tries to emulate the event if not supported.

denchev commented Sep 12, 2011

Yes, setting "orientation" to false fixes the problem. jQuery Mobile tries to emulate the event if not supported.

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Sep 20, 2011

Contributor

@jaybuys, @tigbro, @jzaefferer, @MartinMa, @tunylund, @depeele, @TZAdvantage, and @denchev

Judging from the comments here and the fact that using the jqm emulation produces the desired result it sounds like everyone expects this to be a post orientationchange event. That is an event that is triggered when the orientation changes and the document element size has been altered. The docs are actually ambiguous as to whether the orientation value will be pre/post change.

Triggers when a device orientation changes (by turning it vertically or horizontally). When bound to this event, your callback function can leverage a second argument, which contains an orientation property equal to either "portrait" or "landscape". These values are also added as classes to the HTML element, allowing you to leverage them in your CSS selectors. Note that we currently bind to the resize event when orientationChange is not natively supported.

There's a case to be made for having an orientation change event that fires before the document element has resized, but for now after I double check with the team I'll look into making the current orientationchange event include the post resize orientation value and clarifying the documentation a bit.

[edit] window -> document element

Contributor

johnbender commented Sep 20, 2011

@jaybuys, @tigbro, @jzaefferer, @MartinMa, @tunylund, @depeele, @TZAdvantage, and @denchev

Judging from the comments here and the fact that using the jqm emulation produces the desired result it sounds like everyone expects this to be a post orientationchange event. That is an event that is triggered when the orientation changes and the document element size has been altered. The docs are actually ambiguous as to whether the orientation value will be pre/post change.

Triggers when a device orientation changes (by turning it vertically or horizontally). When bound to this event, your callback function can leverage a second argument, which contains an orientation property equal to either "portrait" or "landscape". These values are also added as classes to the HTML element, allowing you to leverage them in your CSS selectors. Note that we currently bind to the resize event when orientationChange is not natively supported.

There's a case to be made for having an orientation change event that fires before the document element has resized, but for now after I double check with the team I'll look into making the current orientationchange event include the post resize orientation value and clarifying the documentation a bit.

[edit] window -> document element

@tunylund

This comment has been minimized.

Show comment
Hide comment
@tunylund

tunylund Sep 21, 2011

I would like to see both pre and post-events. We need the events to render some heavy ui so that the ui does not look broken for too long.

I would like to see both pre and post-events. We need the events to render some heavy ui so that the ui does not look broken for too long.

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Sep 23, 2011

Contributor

@tunylund

I would too but it may not be possible depending on the browser implementation. This issue is next on my list though more and more its looking like we might just default to the resize :(

Contributor

johnbender commented Sep 23, 2011

@tunylund

I would too but it may not be possible depending on the browser implementation. This issue is next on my list though more and more its looking like we might just default to the resize :(

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Sep 26, 2011

Contributor

@toddparker @scottjehl

Proposed solution:

johnbender@93c5ad1

If you guys can test the results on your devices locally with the following it would be brilliant:

git checkout -b orientationchange master
git pull https://github.com/johnbender/jquery-mobile.git master
# ... test test test ....

This doesn't address the issue of the event firing before the screensize has changed on Android but at least the user will get the correct value from event.orientation. If all looks good I'll add tests and then update the docs to make it clear when the event is firing and what the users can expect in terms of screensize from various devices.

[update] small change to the commit

Contributor

johnbender commented Sep 26, 2011

@toddparker @scottjehl

Proposed solution:

johnbender@93c5ad1

If you guys can test the results on your devices locally with the following it would be brilliant:

git checkout -b orientationchange master
git pull https://github.com/johnbender/jquery-mobile.git master
# ... test test test ....

This doesn't address the issue of the event firing before the screensize has changed on Android but at least the user will get the correct value from event.orientation. If all looks good I'll add tests and then update the docs to make it clear when the event is firing and what the users can expect in terms of screensize from various devices.

[update] small change to the commit

@johnbender johnbender closed this in 57079e1 Oct 4, 2011

@s6mna9

This comment has been minimized.

Show comment
Hide comment
@s6mna9

s6mna9 Oct 26, 2011

Thanks, I'm new with JQM. It is fixed BUT I have tested with Samsung Galaxy S (Android 2.2), the event fires 2 times.

s6mna9 commented Oct 26, 2011

Thanks, I'm new with JQM. It is fixed BUT I have tested with Samsung Galaxy S (Android 2.2), the event fires 2 times.

@tunylund

This comment has been minimized.

Show comment
Hide comment
@tunylund

tunylund Oct 26, 2011

Indeed, and for that matter HTC Sensation fires only one orientation change event but too early. The window is wrong size when it fires. HTC Desire in the other hand fires 3 orientation change events. Depending on orientation change or resize event is quite dangerous.

Is it possible for jquerymobile to wrap these platform specific behaviours in some custom event? For example the way that jquery wraps all different ajax implementation in one api.

Indeed, and for that matter HTC Sensation fires only one orientation change event but too early. The window is wrong size when it fires. HTC Desire in the other hand fires 3 orientation change events. Depending on orientation change or resize event is quite dangerous.

Is it possible for jquerymobile to wrap these platform specific behaviours in some custom event? For example the way that jquery wraps all different ajax implementation in one api.

@johnbender

This comment has been minimized.

Show comment
Hide comment
@johnbender

johnbender Oct 26, 2011

Contributor

@tunylund

Yah, I noted that in the message before the commit. The change only gets the user the right value, but because the different browsers fire the event at different times, most importantly after the resize has occurred, we don't have an easy way of making sure the event happens when the screen is the right size. We might address this post 1.0, but not before.

@samnan9

We'll hopefully try and address the quirks here but the combination of the event firing many times per orientation change in conjunction with the poor consistency in timing is going to make it difficult if not impossible. For sure this won't be fixed before 1.0.

Contributor

johnbender commented Oct 26, 2011

@tunylund

Yah, I noted that in the message before the commit. The change only gets the user the right value, but because the different browsers fire the event at different times, most importantly after the resize has occurred, we don't have an easy way of making sure the event happens when the screen is the right size. We might address this post 1.0, but not before.

@samnan9

We'll hopefully try and address the quirks here but the combination of the event firing many times per orientation change in conjunction with the poor consistency in timing is going to make it difficult if not impossible. For sure this won't be fixed before 1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment