12

I am trying to restrict user to scroll if they touch on an iframe. So, if they touch on body, they can scroll.

Wondering why below code works fine in Mobile Chrome, but not working in Mobile Safari. Any way to fix this for safari?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
        <style>
            .overflowHidden {
                position:relative;
                overflow-y:hidden;
            }
            .overflowAuto {
                -webkit-overflow-scrolling: touch;
                overflow: auto;
            }
        </style>
    </head>
    <body>
        <section>
            <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
            <iframe id="appSimulator" style="background: #000000;" width="189px" height="400px" frameborder="0" scrolling="no"></iframe>
            <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
        </section>
        <script type="text/javascript">
            document.body.addEventListener('touchstart', function(){
                document.body.style.overflow="auto";
                $('body').removeClass('overflowHidden');
                $('body').addClass('overflowAuto');
            }, false)
            document.body.addEventListener('touchend', function(){
                document.body.style.overflow="hidden";
                $('body').removeClass('overflowAuto');
                $('body').addClass('overflowHidden');
            }, false)
        </script>
    </body>
</html>

EDIT

Example for Mobile Chrome - This is what I want in Safari mobile

enter image description here

Thanks.

EDIT 2

Thank you for the help from muecas.

Here is the current result from Safari Mobile

enter image description here

Current Code

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <style>
            body {
                -webkit-overflow-scrolling: touch;
            }
            .iframeContainer, iframe {
                width: 189px;
                height: 405px;
            }
            .iframeContainer {
                overflow: auto;
            }
        </style>
    </head>
    <body>
        <section>
            <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
            <div class="iframeContainer">
                <iframe id="appSimulator" src="https://appetize.io/embed/keyyyyyyy?device=iphone5s&scale=50&autoplay=false&orientation=portrait&deviceColor=black&language=zh-Hant" frameborder="0" scrolling="no"></iframe>
            </div>
            <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
        </section>
    </body>
</html>

if I set .iframeContainer { overflow: hidden; }

enter image description here

Pak Ho Cheung
  • 1,382
  • 6
  • 22
  • 52
  • 1
    That code, if managed to get it working, will prevent all scrolling on the page, no matter if you touch the iframe or not. `touch` on the iframe will not trigger `touch` in the main html. So the question is, the problem is not overflowing the `html` or hook to iframe events to prevent scroll? Or both? – muecas May 18 '18 at 15:37
  • @muecase When I try to test this code in mobile with Chrome browser, the body view would not scroll if I touch on the iFrame and scroll up or down. But when I do this in mobile with Safari, nothing happens like just scroll up or down with no event. The problem I am hitting is I have a scroll view inside iFrame. Here is the thing I am trying to embed. https://appetize.io/ When I try to scroll their simulator, only body would scroll. The view in simulator (iFrame) does not work. – Pak Ho Cheung May 18 '18 at 21:38
  • The container html must be scrollable? Cause is your example in Chrome you can't scroll the main html either. – muecas May 19 '18 at 14:09
  • In chrome mobile, I can scroll. Please see my edit – Pak Ho Cheung May 19 '18 at 21:26
  • Thanks for the graphic example of what to achieve. I’ll try my best to help you out. – muecas May 19 '18 at 23:00
  • Thanks a lot. Stuck in here for a few days already. – Pak Ho Cheung May 20 '18 at 00:30

2 Answers2

7

The main problem with Safari iOS is that the iframe tag is treated as some sort of responsive element, and will act strange to its size, and contained element (loaded HTML) sizes. I tested using an iframe with real content, so it will be fully scrollable. Using the same code as in you example, Safari iOS showed the iframe with full height of the contained html content event with a width and height defined.

To solve the problem you need to include the iframe in a block container, and then set the block container size (width and height) and overflow to auto, and add the vendor attribute to the body to allow the iframe to be scrolled properly. Also, dont forget to set the iframe as scrollable.

You can discard the js implementation.

I tested this on every desktop browser, Safari iOS and Mobile Chrome.

You may also want to check this link when the responsive content inside an iframe is discussed.

Hope it helps.

Main html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <style>
        body {
            -webkit-overflow-scrolling: touch;
        }
        .iframeContainer, iframe {
            width: 200px;
            height: 200px;
        }
        .iframeContainer {
            overflow: auto;
        }
    </style>
</head>
<body>
    <section>
        <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
        <div class="iframeContainer">
            <iframe id="appSimulator" frameborder="0" src="scrolling.html" scrolling="yes"></iframe>
        </div>
        <p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p><p>hello</p>
    </section>
</body>
</html>

Loaded iframe:

    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <style>
        body {
            background-color: black;
            color: white;
        }
    </style>
</head>
<body>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
    <p>hello</p>
</body>
</html>
muecas
  • 4,265
  • 1
  • 8
  • 18
  • Hi. Thanks for all the help. I think it is really close. The only problem I have now is the ```appSimulator``` would bounce if I scroll up or down. – Pak Ho Cheung May 22 '18 at 03:42
  • I am thinking the bounce comes from the third-party ```src``` – Pak Ho Cheung May 22 '18 at 03:50
  • @PakHoCheung bounce? Can i see an example of that? – muecas May 22 '18 at 11:01
  • thank you for your help. I uploaded a gif for what I see in Safari mobile – Pak Ho Cheung May 22 '18 at 12:12
  • @PakHoCheung so the requested behavior is achieved. You can scroll the main page and the iframe too. What’s missing? – muecas May 22 '18 at 12:18
  • The content of the app inside the simulator is scrollable. So it is so rare when I scroll the content, I can see a bounce at the same time. Let me show you the content – Pak Ho Cheung May 22 '18 at 12:23
  • @PakHoCheung I thought that the iframe should be scrollable. – muecas May 22 '18 at 12:29
  • @muecase Updated the new gif. If I set the iframe to be not scrollable, it also means I cannot scroll the content of simulator? – Pak Ho Cheung May 22 '18 at 12:39
  • @PakHoCheung the problem with the bouncing scroll is that, in order to remove it, you need to hace access to the contained page on the iframe, to apply some hacks there. Otherwise is not possible. have you tried `overlofw: hidden` on the div that contains the iframe? – muecas May 22 '18 at 12:42
  • Do you think if I know the iframe's position like its width or height, I can check if user touch on the iframe's position, I can just disable scroll on body? – Pak Ho Cheung May 22 '18 at 12:46
  • @PakHoCheung well, not on Safari iOS; it will not fire the touch event over an iframe. :-( So the embeded app will never scroll? – muecas May 22 '18 at 12:47
  • It will scroll but also scroll the whole body haha @muecas – Pak Ho Cheung May 22 '18 at 12:48
  • @PakHoCheung how's that? You cant scroll iframe and body at the same time. Only if you reach top or bottom. Is the expected behavior. – muecas May 22 '18 at 12:50
  • please see the last gif – Pak Ho Cheung May 22 '18 at 12:57
  • @PakHoCheung ok, one thing i don't get, whats the point of preventing the scroll over iframe, if the iframe has no scroll? Or am i missing something? – muecas May 22 '18 at 13:01
  • It looks more professional if I scroll the iframe and the iframe doesn't have any bounce but the content of the simulator can be scrolled. @muecas – Pak Ho Cheung May 22 '18 at 13:05
  • @PakHoCheung i know, but the problem is that, if you cant control the iframe content, then you can't do it. You would need to remove the overflow or prevent touch move inside the iframe in order to do that. From outside the iframe (and with the source iframe out of control - loaded from another domain -) that's not possible. – muecas May 22 '18 at 13:10
  • oh i see. thank you for the help. But, I am wondering why I can do it in Chrome Mobile, but cant do it in Safari Mobile. Is it because as you said the iframe tag of safari is treated as some sort of responsive element. @muecas – Pak Ho Cheung May 22 '18 at 13:12
  • @PakHoCheung the problem is that on Safari, the touch event does not bind to the container html, so it's not fired on you html, only in the app html. I testes several times :-( – muecas May 22 '18 at 13:19
  • such a pain. Anyways, thanks for all the help. you are the best person I see in here:) – Pak Ho Cheung May 22 '18 at 13:20
  • @PakHoCheung sorry i couldn't fully solve your problem :-( – muecas May 22 '18 at 13:24
  • @meucas It is ok. At least I get one more option of what user can see haha – Pak Ho Cheung May 22 '18 at 13:25
  • @PakHoCheung i guess i will not get the bounty haha i need to try harder ;-) – muecas May 23 '18 at 10:34
2

It seems touch event works well but overflow is not.
I am not sure what your html looks like, however you can try these:

  1. hidden:
    body { /* position can be fixed */ position:relative; overflow-y:hidden; }

  2. auto:
    body { -webkit-overflow-scrolling: touch; overflow: auto; }

Wicky
  • 166
  • 6
  • How can I write -webkit-overflow-scrolling in Javascript? Thanks. – Pak Ho Cheung May 15 '18 at 11:09
  • You can set them as class style, like `.overflow-hidden{position:relative;overflow-y:hidden;}`. Then what you need is to use `$('body').removeClass('overflow-auto')` and `$('body').addClass('overflow-hidden')`. – Wicky May 15 '18 at 12:21
  • Still not work. Updated the whole html file that produces this issue in Safari mobile. – Pak Ho Cheung May 15 '18 at 15:59
  • Your problem is that **Overflow:hidden not working in safari browser** which there is a some question [here](https://stackoverflow.com/questions/28407499/overflowhidden-not-working-in-safari-browser). Suggestion from him is to add the same class to html tag. I hope it will help you. – Wicky May 16 '18 at 02:49
  • That post also cannot fix MOBILE safari. Anyways, thank you for the help – Pak Ho Cheung May 16 '18 at 14:04