11

I have a position:fixed div on a scrolling web page.

At first the event works, but when the page scroll, while the fixeed divs stays in place, its "touch" zone seems to change (it seems to scroll - except on top of another div, or depending on the page layout...). Eventually no touch event is received any more if you scroll too much. Sometimes the underlying div receives the event instead.

Here's the sample:

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;">
    <meta name="apple-mobile-web-app-capable" content="yes" />

<style>
#fixed {
  position: fixed;
  width:200px;
  height:200px;
  z-index:1;
  background: rgba(100,0,0,0.5);
}

#scrolling {
  display: block;
  position: absolute;
  top: 100px;
  left: 100px;
  width:200px;
  height:999px;
  background: rgba(0,100,0,1);
}
</style>
</head>

<body>
  <div id="fixed"     ontouchend="alert('touch fixed')"></div>
  <div id="scrolling" ontouchend="alert('touch scrolling')"></div>
</body>

When you scroll enough and touch the red "fixed" div on its left side, nothing happens (no alert). However, on the right side (above the green scrolling div) it works... ?!

Looks like a Safari bug to me. Do you experience the same? Any idea for a workaround? (Iscroll is out of question - too slow)

Thank you, LC

lacorbeille
  • 325
  • 1
  • 4
  • 8

7 Answers7

12

I found a relatively strange solution to this bug. By adding a touchstart event listener and a blank event handler, it somehow seems to move the touch area on manual touch. I do not know if this is a solution for the JavaScript scroll issue.

Code:

document.getElementsByTagName("body")[0].addEventListener("touchstart",function(){});

Credit for finding this method goes to pamelafox in this github bug discussion.

troelskn
  • 115,121
  • 27
  • 131
  • 155
Gaurav Shetty
  • 461
  • 4
  • 10
  • This worked for me. I was having a problem where a fixed element was not receiving touch events when the page scrolled down. Fixed! – tolmark Sep 07 '12 at 16:21
  • Likewise, I had a programmatically fixed div with anchor tags beneath it. The div wasn't receiving the touch events but the anchors were. Implementing the above solution worked for me. – James Feb 19 '13 at 16:36
  • The code has a slight syntax error. It should be: document.getElementsByTagName("body")[0].addEventListener("touchstart",function(){}); – bentsai Jul 16 '13 at 04:37
  • This code, with the added `[0]`, did work for me on iOS 5, iPod Touch – Linus Unnebäck Sep 21 '13 at 19:45
  • I can't believe it worked! I had to add it to the `position: fixed` element, not the body, btw. – iangilman Nov 14 '16 at 23:12
2

I'm having the same issue. It seems to be a z-index problem, when the divs are moved programmatically (with animations, etc.): the div in fixed position doesn't work properly since the user doesn't touch again for scrolling. Only in this last case the divs seems to be recomputed correctly.

Andrea
  • 21
  • 2
1

I ran into the same issue using a fixed position navigation that scrolls the user around the page using jQuery animation. I don't believe it's a z-index issue. What I found is that when the animation moves the viewport, the fixed position element is actually still at the previous location until the user touches and moves the screen. At that point the position of the nav is updated. More information and demo here: http://bit.ly/ios5fixedBug

1

I had this problem. The way I got round it was to bind to "click" instead of "touchstart".

This meant that my "click" events got messed up (for users not on touch devices) so I detected a hover first and then used the hover to tell me if they were touch users or not. A bit dirty, but it works!

scruffian
  • 697
  • 6
  • 7
1

I found this bug too, but the below seemed to clear it up for me:

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">`

add it to your html header

cjroebuck
  • 2,273
  • 4
  • 30
  • 46
0

This issue may be related to another which has a couple of workarounds posted. Fixed positioning implementation on mobile safari is half-hearted at best.

Fixed position navbar only clickable once in Mobile Safari on iOS5

Community
  • 1
  • 1
Ryan Ore
  • 1,315
  • 17
  • 23
0

Touch events retrieve pageX and pageY - which suggests a position on the 'page' is meant. If the page is scrolled down, the Y coordinate increases and thus fixed elements will be out of reach because their y offset values stay the same. You can check wheter a fixed element has been touched on a scrolled page by this calculation:

var finger = e.touches[0];
var yCalc = finger.pageY - window.pageYOffset;
var touchedElement = document.elementFromPoint(finger.pageX, yCalc);

If you have horizontal scrolling, you have to do the same thing with the x coordinate, of course.

biodiv
  • 607
  • 6
  • 16