Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mobile Safari bug on fixed positioned button after scrollTop programmatically changed...?

I'm just about done a webpage but there is one bug in Mobile Safari (iPhone and iPad iOS 5.0.1) with two buttons that are fixed to the upper and lower right corners..

The buttons are not faded in until after clicking submit on a textbox which opens up to the rest of the page... After the rest of the page is loaded and the buttons are faded in you can click on either of them and they both work...

However, clicking them causes a programmatic scroll and after that scroll is complete you can no longer click on either of the buttons until you physically scroll the page with your finger even just a tiny one pixel scroll...

What I have noticed is that after the programmatic scrolling if you tap just slightly below the TOP button you see the highlight as if you were tapping the BOTTOM button and the action of the bottom button is processed, which tells me the bug is that when scrolling programmatically the fixed position button still moves with the rest of the page and doesn't go back to it's fixed position until an actual touch scroll is performed....

Does anyone know a way around this..?

I've added a popup that shows which button was pressed so you can test it, remember after the first press of the down button (which works) trying pressing down again, it won't work, but click just below the up button and you'll see the down button actions happening....

http://www.tsdexter.com/ceos

thanks for the help.

Thomas

(also if you can point me to where I can submit a bug to Apple that'd be good too, unless one already has been)

EDIT: just click either of the submit arrows, you don't need to enter a wage/salary it has defaults

EDIT 2: Here is a simpler example to show the same issue..

http://www.tsdexter.com/MobileSafariFixedPosBug.html

EDIT 3: Bug reported to Apple

like image 314
tsdexter Avatar asked Jan 06 '12 01:01

tsdexter


4 Answers

We also encountered this bug on 2 different iPad applications, for us the best fix was to temporarily remove the fixed position from the fixed element once the animated scroll had finished, then use window.scroll with the vertical value we’d just performed the animated scroll to, then finally re-apply the position fixed style. It does cause a very minor blip as the ipad re-renders the element but its preferable to the bug.

var $fixedElement = $('#fixedNavigation');
var topScrollTarget = 300;
$("html:not(:animated),body:not(:animated)").stop().animate({ scrollTop: topScrollTarget }, 500, "swing", function(evt) {
    $fixedElement.css({ "position": "relative" });
    window.scroll(0, topScrollTarget );
    $fixedElement.css({ "position": "fixed" });
});
like image 185
Dominic Warren Avatar answered Nov 06 '22 03:11

Dominic Warren


I got around it by adding a 101% high div then (almost) immediately removing it.

Try:

<style>
.iosfix {
  height: 101%;
  overflow: hidden;
}
</style>

and when you scroll:

window.scrollTo(0, _NEW_SCROLLTOP_);
$('body').append($('<div></div>').addClass('iosfix'));
setTimeout(function() {
  $('.iosfix').remove();
}, 500);

It also works with jQuery.scrollTo.

See an example here.

like image 13
Chad Smith Avatar answered Nov 06 '22 03:11

Chad Smith


I had multiple links on separate fixed elements (a modal popup + fixed blackout div + normal fixed toolbar) and none of these answers were working so I had a tinker about trying variations on the same theme. Like all these suggest the key is getting elements re-rendered.

Initially I tried adding 1px to the width of fixed elements and removing it. This did cause re-rendering, but re-rendered elements became mis-aligned with non re-rendered elements - another result of this iOS bug I suspect. The answer was to simply add to the width of the body and subtract again (or set to auto), ie:

//jQuery will calculate the current width and then +1 to this and set it
$('body').css('width', '+=1');

//Remove width css
setTimeout(function() {
  $('body').css('width', '');
}, 1);

If not using jquery you will need to get the current width of body +1px to it and then set the width.

like image 7
Ed Kirk Avatar answered Nov 06 '22 02:11

Ed Kirk


Here is my solution if like me, none of the previous solution is working for you.

The trick is:

  • Do your scroll (Animate or scrollTo, etc.)
  • Just after your scroll, position:absolute your fixed elements
  • On the 'touchmove' event, restore the position:fixed

Here an example:

  $('body').animate({
       scrollTop: newPos}, 1000, 'jswing', function () {
          $('header').css({position:'absolute', top:newPos});
  });

  $(document).bind('touchmove',function(){
       $('header').css({position:'fixed', top:'0px'});
  });   

I used the same trick for sticky footer and other floating fixed elements.

like image 4
Stephane Brillant Avatar answered Nov 06 '22 02:11

Stephane Brillant