dimsemenov / Magnific-Popup

Light and responsive lightbox script with focus on performance.
http://dimsemenov.com/plugins/magnific-popup/
MIT License
11.38k stars 3.49k forks source link

Scrolling and exiting popup on mobile #12

Open o-l-e opened 11 years ago

o-l-e commented 11 years ago

Hi, i was wondering if you have any tips on how to prevent the main page from scrolling when you scroll through the first of the ajax popup examples?

To be clear: On an iphone, tap on the ajax popup "Load content via ajax) on an iOS device. What happens is that when you scroll downwards to the bottom of the popup content, and then close it, the entire main page has also scrolled down. This does not happen when doing the same on a desktop (Safari), only on iPhone.

Is there anything that could be done about this? Any help would be appreciated.

Keep up the good work!

maimairel commented 11 years ago

Also having this issue, Haven't tried yet, but maybe -webkit-overflow-scrolling: touch on .mfp-wrap might help?

dimsemenov commented 11 years ago

Hi,

You may:

a) Set option fixedContentPos:true to trigger same layout on desktop and mobile and add -webkit-overflow-scrolling:touch. But zooming will look ugly and webkit-overflow-scrolling isn't supported by all browsers.

b) Reset the window scroll manually via callbacks after the popup is closed:

var startWindowScroll;

$('.link').magnificPopup(function() {

    // options...

    callbacks: {
      beforeOpen: function() {
        startWindowScroll = $(window).scrollTop();
      },
      close: function() {
        $(window).scrollTop(startWindowScroll);
      }
    }
});

But it might also look hacky.

c) Use conditional lightbox technique and don't open lightbox at all on mobile devices.

Would gladly hear your thoughts regarding this issue and what solution should I add to official build.

o-l-e commented 11 years ago

I have tried a couple of your suggestions.

a) This actually works well on iPhone 5 with lates iOS(have not tried any other devices), adding the -webkit-overflow-scrolling: touch to the .mfp-wrap, combined with the fixedContentPos: "true" seems to solve the problem. Also it removes the overlay above the ajax popup. Now what browsers would this affect? Android? You are right though, the zooming is ugly.

b) This works, and although hacky it is better than nothing at all. The downside of this solution is that you actually see the background scrolling through the opacity overlay.

c) I see your point here, but the popup works really well for this kind of content, and i would really like to use it without the conditional technique. What makes Magnific Popup so nice is that it works better than other lighboxes/modals on mobile.

Anyway thanks for the help!

o-l-e commented 11 years ago

Hi again,

after trying out different scenarios, i am about to give up trying to get the active ajax popup to work smoothly in iOS. I wish there was a solution, but after trying out the things on the previous message, i found that the scrolling is still a bit jagged and slow in iOS (also tried it on an iPad).

But, while trying your suggested solution with the disableOn "screen sizes below 600" function, the browsing experience is surprisingly quite nice on an iPhone. But this does raise another issue for the iOS on iPad (and probably other tablets), which are much wider than the < 600 in the documentation.

Update: I managed to get the disableOn to work with Modernizr (i think), and would like to hear from anyone if this works well on all touch devices?

This is what i have, in the head place modernizr (of course):

<script src="modernizr.js"></script>

Then in the disableOn function:

disableOn: function() {
    // if( $(window).width() < 600 ) {
        // return false;
    // } 
    // return true;

    if (Modernizr.touch){
        return false;
    }
    return true;
}

If this is a sustainable method, maybe this could be something to be added in the documentation? Any feedback would be appreciated :)

kerns commented 11 years ago

Is it not just a matter of toggling a class on the body tag when the modal is active, with the property “overflow:hidden” ? It might also be necessary to have all the contents of the page wrapped in a single div, but I'm not sure...

uaherwal commented 9 years ago

@dimsemenov , its has been troubling for days I could not scroll on ios, when form was long and you needed to scroll to view submit button, 'every time the input was touched and dragged it won't scroll' you posted comment on Apr 29, 2013, section a. solved my bug, gave me solution.

Many thanks..!!

mediastuttgart commented 9 years ago

i had a similar issue with a fullscreen ajax content popup (also had one with a touch carousel inside the popup) and solved it by adding the following callbacks

callbacks: {
    beforeOpen: function () {
        if (Modernizr.touch) {
            $('body').on('touchmove', function (e) {
                e.preventDefault();
            });
        }
    },
    afterClose: function () {
        if (Modernizr.touch) {
            $('body').off('touchmove');
        }
    }
}
iamkeir commented 9 years ago

I found that fixedContentPos: true in MFP options, combined with -webkit-overflow-scrolling:touch on .mfp-wrap helped me. I had a few issues with scroll flickering so also adding -webkit-transform:translateZ(0) for hardware acceleration also helped.

No fix for zoom though - it is rendered very clunky.

Had a look at how Fancybox solve this? autoCenter or something... If I find time, I'll create a test case.

iamkeir commented 9 years ago

Correction, this is what I had to do in the end:

$('.lightbox').magnificPopup({
  fixedContentPos: true,
  callbacks: {
    beforeOpen: function() { $('html').addClass('mfp-helper'); },
    close: function() { $('html').removeClass('mfp-helper'); }
  }
});
.mfp-wrap {
  -webkit-overflow-scrolling: touch;
  -webkit-transform: translateZ(0);
}

html.mfp-helper {
  height: 100%;

  body {
    overflow: hidden;
    height: 100%;
    -webkit-transform: translateZ(0);
  }
}
miserte commented 9 years ago

@iamkeir Your correction worked for me. Many thanks for share it.

sjmcpherson commented 9 years ago

Great work @iamkeir works well so far

iamkeir commented 9 years ago

Glad it was useful! I would still like to see how Fancybox solved this. I prefer MagnificPopup but doesn't seem to be an issue with Fancybox. As I said, will try and investigate when I have time - but if anyone else knows, do post!

microcipcip commented 9 years ago

@iamkeir solution works great but you lose the scroll vertical position. You can fix this by adding startWindowScroll = $(window).scrollTop(); suggested by @dimsemenov. The complete solution is:

var startWindowScroll = 0;
$('.link').magnificPopup(function() {
    // options...
    callbacks: {
      beforeOpen: function() {
        startWindowScroll = $(window).scrollTop();
        $('html').addClass('mfp-helper');
      },
      close: function() {
        $('html').removeClass('mfp-helper');
        $(window).scrollTop(startWindowScroll);
      }
    }
});
.mfp-wrap {
  -webkit-overflow-scrolling: touch;
  -webkit-transform: translateZ(0);
}

html.mfp-helper {
  height: 100%;

  body {
    overflow: hidden;
    height: 100%;
    -webkit-transform: translateZ(0);
  }
}
iamkeir commented 9 years ago

@microcipcip thank you, that's a good spot and fix!

Re Fancybox, it suffers a similar problem but opts to address it with JS in its internals (auto centering after scroll)

ghost commented 9 years ago

I used the initial version of iamkeir, but then without the translateZ. That gave some strange issues on my side. Maybe it can help someone else as well. Thanks for the code samples!

dpmango commented 7 years ago

I don't like how the page jumps because of body height 100% and hidden overflow. Another solution that worked for me.

So, the point is that fixedBgPos and fixedContentPos works really well on desktop devises and to have same behavior on mobile, we can simply disable touch event if the height of modal content is less than window height.

var startWindowScroll = 0;
  $('.popup-with-zoom-anim').magnificPopup({
    fixedContentPos: true,
    fixedBgPos: true,
    overflowY: 'auto',
    callbacks: {
      beforeOpen: function() {
        startWindowScroll = $(window).scrollTop();
      },
      open: function(){
        if ( $('.mfp-content').height() < $(window).height() ){
          $('body').on('touchmove', function (e) {
              e.preventDefault();
          });
        }
      },
      close: function() {
        $(window).scrollTop(startWindowScroll);
        $('body').off('touchmove');
      }
    }
  });
.mfp-wrap
  -webkit-overflow-scrolling: touch
  -webkit-transform: translateZ(0)
dotorify commented 7 years ago

@dpmango that worked for me, thanks :)

bs-thomas commented 7 years ago

@dpmango Great fix! Though technically I still don't quite understand why the library couldn't deal with this seamlessly and automatically. Ah well... Thank you!

anaja7 commented 7 years ago

Hello @dpmango!

I can't fix the background scrolling problem in mobile version. http://gama.aastiazaran.com/2017/05/08/christian-louboutin-viva-mexicaba/ I have added:

var startWindowScroll = 0; $('.popup-with-zoom-anim').magnificPopup({ fixedContentPos: true, fixedBgPos: true, overflowY: 'auto', callbacks: { beforeOpen: function() { startWindowScroll = $(window).scrollTop(); }, open: function(){ if ( $('.mfp-content').height() < $(window).height() ){ $('body').on('touchmove', function (e) { e.preventDefault(); }); } }, close: function() { $(window).scrollTop(startWindowScroll); $('body').off('touchmove'); } } });

.mfp-wrap -webkit-overflow-scrolling: touch -webkit-transform: translateZ(0)

But didn't work :( What else can I do, or maybe Im doing it it wrong, can you explain step by step how to fix it pleaseeee!!

Thanks

cc @bs-thomas @dotorify HELP!

Grawl commented 7 years ago

Just faced that issue again.

I found that fixedContentPos: true in MFP options, combined with -webkit-overflow-scrolling:touch on .mfp-wrap helped me. I had a few issues with scroll flickering so also adding -webkit-transform:translateZ(0) for hardware acceleration also helped.

This helped me, but without -webkit-transform:translateZ(0) — all good without that on iOS 10 / Mobile Safari.

mcfarlandonline commented 6 years ago

fixedContentPos: true in MFP options, combined with -webkit-overflow-scrolling:touch on .mfp-wrap fixed the issue for me, as well.

GiorgosK commented 6 years ago

This is what worked for me

.mfp-bg, body.mfp-zoom-out-cur { overflow: hidden !important; margin: 0 !important; padding: 0 !important; height: 100% !important; }

vezhevich commented 6 years ago

@dpmango спасибо тебе, работает!

zdimaz commented 5 years ago

Нифига не работет, это бред а не баг фикс !

Grawl commented 5 years ago

on iOS, there is only way to prevent body scrolling is with JS. I use body-scroll-lock.

Grawl commented 5 years ago

the position: fixed approach causes the body scroll to reset

zdimaz commented 5 years ago

Add body to position fixed the thrash mode and code. Body scroll lock this is another plugin, it’s not bugs fix magnific popup.