8

I set my hero-unit to position fixed after scrolling down to it's position. So for the first 70px of the page the hero-unit scrolls along with the rest until the top reaches the hero-unit which then needs to be fixed.

Not fixed

enter image description here

Fixed

enter image description here

This works fine everywhere and also the ipad except that the position is set to fixed when the scroll is finished instead of during the scrolling like the browser.

I know it's because the scroll event is not fired during the momentum scrolling. I tried to fix this using the following code but it did not work:

document.addEventListener("touchstart", function(){
    $('body').prepend('<p>touch start</p>');
    that.tid = setInterval(function(){
        $.event.trigger(
        { type: "touchcontinuem" }
        );
    },10)
}, false);

document.addEventListener("touchend", function(){ 
    $('body').prepend('<p>touch end</p>'); clearTimeout(that.tid); 
}, false);

$(document).on("touchcontinuem", function(){ 
    $('body').prepend('<p>touch continuem</p>'); 
});

What I want to achieve is that the hero-unit can be set to fixed while the scroll is still busy. If anyone can suggest an improvement or an alternative I would greatly appreciate because i'm stuck right now.

Christophe
  • 4,798
  • 5
  • 41
  • 83
  • Could you provide me a fiddle for this... lemme try it.. – PraJen Jul 24 '14 at 09:20
  • There are may browsers for the IPAD, which one are you refering to?? have you tried it with another browser on the IPAD??? – Tasos Jul 24 '14 at 10:04
  • 1
    I believe this is the way it works, but please note that this only happens the first scrolling movement. the rest, gets fixed. i don't think there is a workaround for this... maybe in future versions of IOS ? – Toni Michel Caubet Jul 24 '14 at 12:00
  • @Tasos mainly the default browser of iPad, safari – Christophe Jul 24 '14 at 13:17
  • Is there a newer version of Safari you can install, maybe those bugs in the browser have been fixed. – Tasos Jul 24 '14 at 13:34
  • 1
    This sounds like a duplicate of this question http://stackoverflow.com/questions/8107722/creating-a-sticky-fixed-position-item-that-works-on-ios-safari – TheHamstring Jul 24 '14 at 14:30
  • @TheHamstring thanks for pointing me to that question, it contained the solution. I did search for this problem for days but never found that question. – Christophe Jul 25 '14 at 07:26
  • 1
    I've been tackling this problem for the last couple projects eventually the clients just de-prioritized it so the final solution was that on touchstart hide via transition opacity 0. Then on touchend fade back in. – jerrylow Jul 26 '14 at 06:33
  • @jerrylow thanks for the suggestion. that might be a solution for other browsers that don't support position:sticky – Christophe Jul 27 '14 at 13:47
  • [Apparently](https://news.layervault.com/stories/30925-ios-8-safari-no-longer-disables-scroll-events) this will no longer be an issue in iOS 8. – Sam Beckham Aug 13 '14 at 08:47

4 Answers4

7

use position: sticky; on the hero element https://developer.mozilla.org/en-US/docs/Web/CSS/position#Sticky_positioning

can i use

while this alone will do the trick in safari, you will still need scroll handling for browsers that don't support sticky positioning.

Sam Beckham
  • 1,218
  • 2
  • 12
  • 23
tommyTheHitMan
  • 482
  • 2
  • 8
  • Depending on what he needs it for, this could be a good fix. The support for it is awful though. – Sam Beckham Jul 26 '14 at 09:23
  • 1
    This is the solution, because Apple does not allow browsers for iOS into the App store unless they are based on WebKit. And WebKit is the engine of Safari that supports `position: sticky;`. Just make sure the style is applied only on iPad. – Julian Jul 26 '14 at 11:40
2

This has been a big issue for me in the past. There are a few workarounds that do work, but they generally break the experience for other browsers/devices.

This kind of works on iOS safari, but it will stop it working on Desktop and a lot of other mobile browsers.

var count = 0;

document.addEventListener("touchmove", function(){
    var data = document.getElementById('data');
    data.innerHTML = count++;
});

There's A great article here that highlights the pros and cons of 3 or 4 different work-arounds for this issue. But—sadly—no real conclusion.

TL;DR - No, there's not a rock-solid fix for this, but there are workarounds that can help.

Sam Beckham
  • 1,218
  • 2
  • 12
  • 23
  • It's a shame. it kind of feels like I'm trying to make something work in older IE ... :) anyway I'll give that a try. I'll be able to only run this for iPad or touch devices so that should not interfere with the desktop behaviour – Christophe Jul 27 '14 at 13:48
0

As pointed by toni there are problem on touchstart/event that trigger only after the end of the scroll. You can try to use the offset from top of the page of the element inside a

 $(window).on("scroll", function() {
   If ( $(element).offset().top < 70 )
      Do thigs
   Else
      Do other
 })

to check where your element is in relation to the top of the page

Emanuele Parisio
  • 1,192
  • 8
  • 27
  • I'm already using this code. it works perfectly on the desktop but not on the iPad. The event will not be fired during the scroll so it doesn't matter if I use offset or not – Christophe Jul 25 '14 at 07:25
0

Assuming that your hero-unit has id="hero-unit", then you can change it's position to fixed using a listener that checks its distance from the top of the screen, like this:

var el = document.getElementById('hero-unit');

document.addEventListener('touchmove', function() {
    var distance = el.getBoundingClientRect().top;

    if (distance <= 0) el.style.position = 'fixed'; // Attach it to the top
    else el.style.position = 'some other value'; // Dethatch it from the top

}, false);
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128