Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript touch event not working in Mobile Safari

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

like image 347
Pak Ho Cheung Avatar asked May 15 '18 02:05

Pak Ho Cheung


People also ask

Does Safari support touch events?

Safari mobile doesn't support touch events.

What is Touchstart JavaScript?

The touchstart event is used to execute a script whenever the user touches an HTML element. On touching a particular element, if the touchstart event is associated with it, it can be used to trigger a javascript function. Note: The touchstart event works only on touch screen devices.

Is click event same as touch?

The touchstart event occurs when the user touches an element. But a click event is fired when the user clicks an element.


Video Answer


1 Answers

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>
like image 109
muecas Avatar answered Sep 28 '22 02:09

muecas