简体   繁体   中英

Touch events within iFrame are not working on iOS

Touch events like touchstart or touchend are not fired when attached to the window inside an IFrame on iOS devices.

Here's a very simple example:

parent.html

<!DOCTYPE HTML>
<html style="height: 100%;">
<head>
    <meta charset="UTF-8">
    <title>Touch Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="height: 100%; margin: 0; overflow: hidden;">
    <iframe style="width: 100%; height: 100%; border: none;" src="child.html"></iframe>
</body>
</html>

child.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Touch Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>    
        body {
            margin: 0;
            padding: 8px;
        }

        div.header {
            margin-bottom: 8px;
        }

        div.text-entry {
            font: 300 1rem/1.25 'Open Sans', 'Helvetica Neue', helvetica, arial, sans-serif;
            color: rgb(64, 64, 64);
        }
    </style>

    <script>
        window.onload = function() {
            function addEvent(event) {
                var div = document.createElement('div');

                div.className = 'text-entry';
                div.textContent = new Date().toLocaleTimeString() + ' Event "' + event.type + '" detected';
                document.body.appendChild(div);
            }

            window.addEventListener('touchstart', addEvent.bind(null), false);
            window.addEventListener('touchend',   addEvent.bind(null), false);
        }
    </script>
</head>
<body>
    <div class="text-entry header">Clicks/touches on the viewport should add some text entries...</div>
</body>
</html>

I've found multiple questions regarding scroll issues on iOS within IFrames and some regarding events, but none seems to have a valid solution for the issue I'm experiencing right now.

I've created a CodePen and a JSFiddle for everyone to play around which show the exact same behavior since both execute the code within an IFrame.

Solution 1: Inside the iframe, add a dummy listener to the document object:

document.addEventListener('touchstart', {}); // in iframe

It seems Safari on IOS denies touch listeners to window unless other DOM objects also have listeners.

Solution 2: Inside the top window, add a dummy listener to any object (including window ):

window.addEventListener('touchstart', {}); // in top window

It seems Safari on IOS denies touch listeners to window in iframes unless the parent also has listeners.

Either of the above solutions works (they're not both needed, only one). Tested on:

  • Safari 9.0 / IOS: 9.3.5
  • Safari 11.0 / IOS: 11.3

Adding following CSS to the IFrame content (child.html in my example above) solved the issue for me:

html, body {
    touch-action: auto;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM