cubiq / iscroll

Smooth scrolling for the web
http://iscrolljs.com
MIT License
12.88k stars 3.81k forks source link

iframe within scrollable content #41

Closed doublejosh closed 13 years ago

doublejosh commented 13 years ago

Curious if there is a workaround known for dealing with iframes within scrollable content?

Everything works fine on page, but when touching the iframe normal scroll behavior takes over including moving the viewport and off-document scrolling with the gray background.

dahjelle commented 13 years ago

The basic problem is that all the events get fired to the iframe instead of to the div, which means iScroll can't get to them.

One way to work around this would be to add a transparent div over the iframe during the scrolling process, and remove it when scrolling is done. I suppose iScroll could even add a feature to do this by default...

doublejosh commented 13 years ago

Interesting concept.

Would be appropriate in some circumstances. Mine was a bit complex because there are some events we do want to make use of in the iframe... so it's a messy situation.

Thanks for the suggestion.

b31 commented 13 years ago

I did not try this myself, but can't you just set "pointer-events: none" to the iframe while scrolling?

dahjelle commented 13 years ago

That's a good point, depending on your browser requirements. More information at https://developer.mozilla.org/en/CSS/pointer-events. The transparent div should work in more browsers, if that's necessary.

I've read that you could have the child iframe accept the events, and then call a function in the parent frame to deal with the events...but that 1) requires that the frames be on the same domain and 2) is awfully messy.

valnub commented 11 years ago

I have the same issue and using "pointer-events: none" on the iframe works fine for scrolling BUT if there is a link inside the iframe, clicking it won't have an effect. How do I work around this?

sjoerdoudman commented 11 years ago

This is a broader problem, since it also occurs using swipe.js, a similar script. It is especially annoying because you cannot put any youtube/vimeo embedded video's in. It has been discussed at http://stackoverflow.com/questions/16595474/youtube-vimeo-iframe-wont-play-in-firefox and https://github.com/bradbirdsall/Swipe/issues/36. The youtube addition of &HTML5=1 to the scr of the Iframe works fine on screen but not on mobile. For Vimeo I cannot find any solution. Is there anyone out there that knows a good workaround, especially for mobile?

heldrida commented 10 years ago

Hi,

I found a solution for this, it happens to be close to what you guys already mentioned but this may be useful for whoever wants to find a fast working resolution for this problem.

I'm assuming a few things, like there's only one iscroll container, here represented as ID. This is not properly tested and needs refactor. It's working in my project, but I changed it here slightly for the example but I guess you'll easily understand what you need to do:

var $iscroll = $('#iscroll');

document.addEventListener('touchstart', function(e) {

if ($iscroll.find('iframe').length > 0){

    $.each($iscroll.find('iframe'), function(k,v){

        var $parent = $(v).parent().first();

        if ($parent.find('.preventTouch').length == 0){

            $('<div class="preventTouch" style="position:absolute; z-index:2; width:100%; height:100%;"></div>')
                .prependTo($parent);

        };

        $parent
            .css('position', 'relative').css('z-index', 1);

    });

    $iscroll.find('.preventTouch').on('click', function(e){
        e.preventDefault();
        e.stopPropagation();
        return false;
    });

};

};

document.addEventListener('touchend', function(e) {

if ($iscroll.find('iframe').length > 0){

    setTimeout(function(){

        var $iscroll = $('#iscroll');

        $iscroll.find('.preventTouch').remove();
        $iscroll.find('iframe').css('z-index', '');
        $iscroll.find('.preventTouch').off('click');

    }, 400);

};

};

Thanks for looking!

manico commented 7 years ago

So, this cannot be fixed? iScroll cannot be used if there is iframe inside scrollable container?

chinochano commented 7 years ago

I couldn't get @heldrida's fix to work so I tried my own approach with the iScroll events.

It's only a partial fix, but works well enough for me. It allows you to start scrolling with the pointer outside of an iframe and continue to scroll over an iframe (already something!). However, if you stop on top of the iframe, pointer-events are set back to "auto", which means you can now click on the iframe links/buttons but not scroll the container page any more. As I said it's a partial fix, but it's clean and straight-forward. Thought it might be useful to some.

iScroll.on('scrollStart', function() {
    $('iframe').css("pointer-events", "none");
});
iScroll.on('scrollEnd', function() {
    $('iframe').css("pointer-events", "auto");
});
kchabra093 commented 7 years ago

@daizumi what happened when user stop mouse on iframe and click on iframe for play video?

chinochano commented 7 years ago

@kchabra093 If you stop scrolling on top of an iframe and click it, the video player (or whatever iframed content) will respond to the click normally. It's only between scrollStart and scrollEnd that pointer events (scrolling, clicking, etc) are ignored.