Skip to content
This repository

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

Open
scottjehl opened this Issue March 23, 2012 · 13 comments
Scott Jehl
Owner

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.

Pamela Fox

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.

Scott Jehl
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.

Mat Marquis
Collaborator
Wilto commented March 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

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

Gaurav Shetty

+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?

Rob Tarr

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

jaredthigpen

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.

Romain Prieto

@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!

William Khoe

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
sebumd commented July 25, 2012

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

Romain Prieto

@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

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

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
Something went wrong with that request. Please try again.