jakiestfu / Snap.js

A Library for creating beautiful mobile shelfs in Javascript (Facebook and Path style side menus)
http://jakiestfu.github.io/Snap.js/
5.99k stars 663 forks source link

iO7 Ratchet doesn't allow safari to hide navigation bars #161

Open joshsilverman opened 10 years ago

joshsilverman commented 10 years ago

On iO7 the Ratchet example has a poor UX because the viewable window is very small. This is because iO7 won't hide the navigation bars if the body doesn't scroll 20px. Ratchet's use of fixed positions disables all body scrolling.

Solution: set the drawer to position:fixed, height:100%, but leave the main content area position:relative.

Problem with that solution: iOS webkit is broken when it comes to scrolling fixed position elements. It ignores z-index therefore your hidden drawer will scroll and not your main area even when the drawer is closed.

Solution:

  snapper.on('animated', ->
    return if ($('.main-view').css('transform') != 'none')
    $('.drawer').removeClass('show')
  )

  setInterval ->
      if ($('.main-view').css('transform') != 'none' && $('.main-view').css('transform') != 'matrix(1, 0, 0, 1, 0, 0)')
          return

      $('.drawer').removeClass('show')
    , 10

  snapper.on('animating', -> $('.drawer').addClass('show'))
  snapper.on('open', -> $('.drawer').addClass('show'))
  snapper.on('drag', -> $('.drawer').addClass('show'))

.drawer {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  height:100%;

  position:absolute;
  width:0;
  overflow: none;

  &.show {
    width:266px;
    z-index: 1;
    position:fixed;
  }
}

.main-view {
  position: relative;
  z-index: 10;
  min-height: 100%;
}

This is a somewhat ugly hack but it worked for me. I'm not sure how it can be integrated into the library, but Snap.js Ratchet is a non-starter on iO7 out of the box.

ebuildy commented 10 years ago

This is because snap set the main content position to absolute, top and bottom = 0. So the view port is actually "little".

This bug appears on all iOS (w/o Ratchet).

Set position to relative will cause other bugs (drawer blink when animating, drawer will stay at top so if you scroll down you will not see the menu etc...).

Where can we test your solution?

Thanks

joshsilverman commented 10 years ago

Sadly the solution has become quite ugly, and only works well in iOS 7. I think I'm gonna rollback to something simpler.

For now, you can check out http://wisr.com/feeds/18 where the above solution is currently implemented.

joshsilverman commented 10 years ago

Actually, I've just disabled touchToDrag and am now satisfied with iOS 6 performance.

Let me explain some of the insanity up above. As you are probably already aware, there is a webkit issue where z-index doesn't work properly for touch. Although, it visually renders correctly, the touch/drag functionality ignores the z-index and grabs the drawer. Therefore, I am dynamically making the drawer absolute when not visible.

Regarding the setInterval usage: this is one of the uglier browser hacks I've done. Unfortunately, addClass/removeClass doesn't work consistently with iOS7. It seems that the previous style class gets reloaded from memory or something periodically. Therefore, I had to continuously set it to absolute by removing the show class -- very very strange! Even setting the class with raw javascript and then immediately reading the class still showed the wrong class. As ugly as this fix is, it has been performant in my testing.

Final hack: when manually closing the drawer via drag, I found often it would be off by one on the transformZ. Therefore, I also hide the drawer when the z coordinate isn't completely reset. This may be irrelevant given that I disabled touchToDrag (because of the flickering), however I left it in in case I want to restore dragging.

Anyway, I am (possibly) satisfied with the UX for now -- I'll continue testing. That said, I really can't wait to delete this code when webkit gets fixed.

ebuildy commented 10 years ago

I believe this bug "Snap disable the navigation bar to be hidden when user scroll down", in iOs ans Android is just killing the UX like you said.

Your fix works Like a charm on m'y Android 4.4 Google chrome browser, but definitively we need a very clean solution, maybe wrap all the Snap stuff with a relative DIV

joshsilverman commented 10 years ago

Please let me know of other examples of decent Snap.js UX on both iOS 6 + 7. Seems to be pretty broken at the moment.

Silverws commented 10 years ago

how to add them??? I want to try-

joshsilverman commented 10 years ago

@Silverws -- were my snipits not clear? They were in scss and coffesscript, but you can transpile both pretty quickly (http://js2coffee.org/ & http://sassmeister.com/).