New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form elements can lose click hit area in position: fixed containers #1

Open
scottjehl opened this Issue Mar 23, 2012 · 13 comments

Comments

Projects
None yet
@scottjehl
Owner

scottjehl commented Mar 23, 2012

Platforms:

  • Android 2.x
  • iOS5

How to reproduce:

  1. Place a form element inside a fixed-positioned container. (button, input, select, etc)
  2. Programatically scroll the page, using window.scrollTo or scrollBy
  3. Buttons will not react to touch/tap until the page is manually scrolled

Note: double-tapping the control does work in iOS5

Reduced Example:

http://jsbin.com/iredok

Bug Tracker ticket(s):

Workarounds:

None known.

@pamelafox

This comment has been minimized.

Show comment
Hide comment
@pamelafox

pamelafox Mar 26, 2012

I found something that seems similar - my touch events were no longer triggered on buttons in a fixed position header after I manually scrolled.

Here's my touch code:
https://gist.github.com/2207028

For some reason adding a touchstart event to body fixed it:
$('body').bind('touchstart', function(e) {
});

I don't understand why, unfortunately.

pamelafox commented Mar 26, 2012

I found something that seems similar - my touch events were no longer triggered on buttons in a fixed position header after I manually scrolled.

Here's my touch code:
https://gist.github.com/2207028

For some reason adding a touchstart event to body fixed it:
$('body').bind('touchstart', function(e) {
});

I don't understand why, unfortunately.

@scottjehl

This comment has been minimized.

Show comment
Hide comment
@scottjehl

scottjehl Mar 29, 2012

Owner

Thanks, @pamelafox. Think that warrants a separate issue? @Wilto filed issue #3 on Android fixed position bugs, which have some iOS5 overlap too I think.

Owner

scottjehl commented Mar 29, 2012

Thanks, @pamelafox. Think that warrants a separate issue? @Wilto filed issue #3 on Android fixed position bugs, which have some iOS5 overlap too I think.

@Wilto

This comment has been minimized.

Show comment
Hide comment
@Wilto

Wilto Mar 29, 2012

Collaborator

@pamelafox: I would be frightened for you if you could fully understand Android’s position: fixed bugs. It’s a disaster.

@scottjehl: I’ll go in and split those up into separate properly-formatted issues later on today, methinks.

Collaborator

Wilto commented Mar 29, 2012

@pamelafox: I would be frightened for you if you could fully understand Android’s position: fixed bugs. It’s a disaster.

@scottjehl: I’ll go in and split those up into separate properly-formatted issues later on today, methinks.

@kentongray

This comment has been minimized.

Show comment
Hide comment
@kentongray

kentongray May 14, 2012

Found a great fix for iOS. Simply add a div triggering scrolling to the end of the document (a height of 101% should work) then create a setTimeout with a delay of 0 to remove the div. This will cause iOS to recalculate the hit position of fixed area elements

kentongray commented May 14, 2012

Found a great fix for iOS. Simply add a div triggering scrolling to the end of the document (a height of 101% should work) then create a setTimeout with a delay of 0 to remove the div. This will cause iOS to recalculate the hit position of fixed area elements

@GauravShetty1016

This comment has been minimized.

Show comment
Hide comment
@GauravShetty1016

GauravShetty1016 May 24, 2012

+1 to the strange fix by pamelafox. Was facing the same issue on manual scroll and have been racking my brains for quite a while. You just saved my life.
Any ideas on why it works? Maybe like kentongray's solution it forces iOS to recalculate position of fixed div elements?

GauravShetty1016 commented May 24, 2012

+1 to the strange fix by pamelafox. Was facing the same issue on manual scroll and have been racking my brains for quite a while. You just saved my life.
Any ideas on why it works? Maybe like kentongray's solution it forces iOS to recalculate position of fixed div elements?

@robtarr

This comment has been minimized.

Show comment
Hide comment
@robtarr

robtarr Jun 7, 2012

I have a fixed position button with a click handler. I tried Pamela's solution but it didn't work in this case.

robtarr commented Jun 7, 2012

I have a fixed position button with a click handler. I tried Pamela's solution but it didn't work in this case.

@jaredthigpen

This comment has been minimized.

Show comment
Hide comment
@jaredthigpen

jaredthigpen Jun 9, 2012

I was able to work around this basically by doing the opposite of what kentongray did.

We have a fixed header with buttons, and are showing/hiding divs. Whenever we show/hide divs, we call ScrollView to reset our window to the top position. If we did this while the screen was scrolled down (not already in top position), the buttons would stop responding until a manual scroll was performed. But if the window was at the top position when we called ScrollView, the bug didn't happen.

We got around this by changing the order of events. We hide the main div we're about to take away, then we call ScrollView, THEN we show our new main div. When performed in this order, our buttons always continue working. It seems that hiding the main view shortens the view into the size of the window, which somehow prevents the bug.

Hope that helps someone.

jaredthigpen commented Jun 9, 2012

I was able to work around this basically by doing the opposite of what kentongray did.

We have a fixed header with buttons, and are showing/hiding divs. Whenever we show/hide divs, we call ScrollView to reset our window to the top position. If we did this while the screen was scrolled down (not already in top position), the buttons would stop responding until a manual scroll was performed. But if the window was at the top position when we called ScrollView, the bug didn't happen.

We got around this by changing the order of events. We hide the main div we're about to take away, then we call ScrollView, THEN we show our new main div. When performed in this order, our buttons always continue working. It seems that hiding the main view shortens the view into the size of the window, which somehow prevents the bug.

Hope that helps someone.

@rprieto

This comment has been minimized.

Show comment
Hide comment
@rprieto

rprieto Jun 20, 2012

@jaredthigpen it definitely helped me, cheers!

I had very similar symptoms (the fixed div not responding to clicks, or jumping to the middle of the page), and like you it didn't happen if the page was already scrolled to the top - and get back to normal after a manual scroll. It's a single page web-app, so the code looked like:

window.scrollTo(0,0);
$('section.current').removeClass('current');
$(target).addClass('current');

After spending hours trying everything else (101% height divs, empty handlers...), your suggestion worked like a charm:

$('section.current').removeClass('current');
window.scrollTo(0,0);
$(target).addClass('current');

I wish I had seen your post or thought about it earlier!

rprieto commented Jun 20, 2012

@jaredthigpen it definitely helped me, cheers!

I had very similar symptoms (the fixed div not responding to clicks, or jumping to the middle of the page), and like you it didn't happen if the page was already scrolled to the top - and get back to normal after a manual scroll. It's a single page web-app, so the code looked like:

window.scrollTo(0,0);
$('section.current').removeClass('current');
$(target).addClass('current');

After spending hours trying everything else (101% height divs, empty handlers...), your suggestion worked like a charm:

$('section.current').removeClass('current');
window.scrollTo(0,0);
$(target).addClass('current');

I wish I had seen your post or thought about it earlier!

@pixelfreak

This comment has been minimized.

Show comment
Hide comment
@pixelfreak

pixelfreak Jul 17, 2012

I too have a button that is fixed at the bottom and I couldn't get position:fixed; to stay at the bottom on Android 2.x until I added the following:

$('#docked-nav').css('-webkit-transition', '-webkit-transform 0.5s').css('-webkit-transform', 'translateX(0px)');

Don't ask me why it works, it's a lucky guess :)

The button doesn't respond to tap once scrolled though. @pamelafox fix did not work for me.

pixelfreak commented Jul 17, 2012

I too have a button that is fixed at the bottom and I couldn't get position:fixed; to stay at the bottom on Android 2.x until I added the following:

$('#docked-nav').css('-webkit-transition', '-webkit-transform 0.5s').css('-webkit-transform', 'translateX(0px)');

Don't ask me why it works, it's a lucky guess :)

The button doesn't respond to tap once scrolled though. @pamelafox fix did not work for me.

@sebumd

This comment has been minimized.

Show comment
Hide comment
@sebumd

sebumd Jul 25, 2012

@rprieto Where did you put that code? $('body').scroll?

sebumd commented Jul 25, 2012

@rprieto Where did you put that code? $('body').scroll?

@rprieto

This comment has been minimized.

Show comment
Hide comment
@rprieto

rprieto Jul 26, 2012

@sebumd For me the problem happened when scrolling while "changing page". Since it's a single-page web app, changing page is really custom code that changes the visibility of certain DIVs:

function changePage(target) {
    window.scrollTo(0,0);  // Go back to the top
    $('section.current').removeClass('current');   // Hide the current div
    $(target).addClass('current');   // Show the new div instead
}

// When the user clicks to see the third tab
changePage('#tab3');

So now it looks like:

function changePage(target) {
    $('section.current').removeClass('current');
    window.scrollTo(0,0);  // Do this while all "pages" (divs) are hidden
    $(target).addClass('current');
}

I hope it's a bit clearer.

rprieto commented Jul 26, 2012

@sebumd For me the problem happened when scrolling while "changing page". Since it's a single-page web app, changing page is really custom code that changes the visibility of certain DIVs:

function changePage(target) {
    window.scrollTo(0,0);  // Go back to the top
    $('section.current').removeClass('current');   // Hide the current div
    $(target).addClass('current');   // Show the new div instead
}

// When the user clicks to see the third tab
changePage('#tab3');

So now it looks like:

function changePage(target) {
    $('section.current').removeClass('current');
    window.scrollTo(0,0);  // Do this while all "pages" (divs) are hidden
    $(target).addClass('current');
}

I hope it's a bit clearer.

@kirtipriya

This comment has been minimized.

Show comment
Hide comment
@kirtipriya

kirtipriya Aug 22, 2013

I faced the same problem: I had a fixed positioned header having a back button.
When the page is programatically scrolled, the click event of back button stopped working.
My workaround was same as the above:

$(document.bind('silentscroll', function(e,data){
$(this).unbind(e);
$("div[data-role='header']").removeClass("ui-header-fixed");
window.scrollTo(0, newPos);
$("div[data-role='header']").addClass("ui-header-fixed");

)};

kirtipriya commented Aug 22, 2013

I faced the same problem: I had a fixed positioned header having a back button.
When the page is programatically scrolled, the click event of back button stopped working.
My workaround was same as the above:

$(document.bind('silentscroll', function(e,data){
$(this).unbind(e);
$("div[data-role='header']").removeClass("ui-header-fixed");
window.scrollTo(0, newPos);
$("div[data-role='header']").addClass("ui-header-fixed");

)};

@fubizitch

This comment has been minimized.

Show comment
Hide comment
@fubizitch

fubizitch Jan 19, 2014

Here is a way around the bug without a hack.

Instead of having the mobile site scroll in the body, disable body scrolling, set height to 100%, and then use a container div for the scrolling instead. This way the fixed elements are outside of the scrollable area, making them immune to this bug.

I tried all the hack solutions out there, but all of them had this bug. Only after separating the fixed elements and the scroll area was the issue fixed.

Chris

fubizitch commented Jan 19, 2014

Here is a way around the bug without a hack.

Instead of having the mobile site scroll in the body, disable body scrolling, set height to 100%, and then use a container div for the scrolling instead. This way the fixed elements are outside of the scrollable area, making them immune to this bug.

I tried all the hack solutions out there, but all of them had this bug. Only after separating the fixed elements and the scroll area was the issue fixed.

Chris

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