Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text selection bug in Mobile Safari with iframes and ontouchstart

In my web app, I have iframes at varying z-indices. I am detecting touchstart events on some elements in the iframes. However, if I have a text input field overlapping an element capturing touchstart, the input field starts behaving erratically: tapping a second time in the field un-focuses it, you are unable to select any text, but you are able to type in the text field.

It appears that the only solution might be to stop capturing touchstart events on the background frame. I'd prefer a solution like a transparent div to capture the events as an intermediary, but I haven't yet gotten that working. Are there other workarounds?

Sample page is at jsfiddle, but here's the code:

<!DOCTYPE html> 
<html> 
    <head> 
        <style type='text/css'> 
            iframe {
                position:absolute;
            }
            #background {
                border: solid 3px red;
                z-index:1;
                width: 20em;
                height: 20em;
            }
            #foreground, #foreground2 {
                border: solid 2px yellow;
                z-index:2;
                top: 15em;
                height: 5em;
            }
            #foreground2 {
                top: 22em;
            }
        </style> 

        <script type='text/javascript'> 
            window.onload=function(){
                document.getElementById("foreground").contentDocument.write("<input type='text' value='text'/><input type='text'/>");
                document.getElementById("foreground2").contentDocument.write("<input type='text' value='text'/><input type='text'/>");

                document.getElementById("background").addEventListener("touchstart", function() {
                    console.log("touch");
                });
            }
        </script> 
    </head> 
    <body> 
        <iframe id=background></iframe> 
        <iframe id=foreground></iframe> 
        <iframe id=foreground2></iframe> 
    </body>
</html> 
like image 515
David Alan Hjelle Avatar asked Jul 29 '11 17:07

David Alan Hjelle


People also ask

Does iframe work on Safari?

sandbox attribute for iframes is Fully Supported on Safari 7.1, which means that any user who'd be accessing your page through Safari 7.1 can see it perfectly.

Why iframe is not working in Safari?

Safari will not allow a web app displayed in an iframe to set/store cookies -> Safari rejects it with "bad csrf" token. I was able to make it work with a change of preferences in Safari. In Safari's Preferences, select Privacy tab, and disable "Prevent cross-site tracking".


1 Answers

While this thread is pretty old now I just wanted to confirm that this bug ist still persistent in the latest iOS Version (8.4) on all devices (iPhone/iPad).

After some testing, I can confirm it always appears under the following circumstance:

  • When using an iframe/object/embed HTML-tag for displaying HTML content in combination with javascript touch event bindings (touchstart/touchend etc..) on elements inside this HTML content. Once the user touches a input element inside of this iframe/object/embed tag a second time (sometimes more) everything he is trying to input via the on screen keyboard doesn't appear anymore inside the input field. (interestingly the word suggestions above the keyboard are still reacting to everything the user types, it just doesn't appear in the input field anymore). Sometimes it is possible to delete content via backspace inside the input field but not add anything.

The following variants seem to exist:

  1. A touch event is bound directly on the input element leading to this error.

  2. A touch event is bound on a parent element with the input element inside it (doesn't have to be a direct child).

  3. The input element is visually sitting on top of an element with a touch event binding. It doesn't matter where this element is inside the DOM or if there are overlaying elements between the touch bound element and the input field. The touch bound element also doesn't have to be visible for this to happen (like when other elements are on top of it). Once the user touches an area of the input field where the touch bound element is behind, the bug appears. This is interesting, because if the input element only partly overlays the touch bound element, touching the part of the input where the touch bound element is not behind will not lead to this bug.

Solutions: First: it doesn't seem to help if you experiment with preventDefault/stopPropagation and other things like that on the touch bound element. It doesn't matter what happens with the event/touch binding on the bound element (I tested it, it doesn't get called/triggered when the bug appears). Even CSS solutions like 'pointer-events: none' on the touch bound element don't help. So the following solutions are our only hope so far:

  1. Dynamically bind touch events like suggested in this thread, so that you only have them active when you really need them and remove them when not, to prevent all of the 3 cases written above.

  2. Move elements or containers with touch event bindings out of the way when an input element is up front. It is enough to use CSS transforms etc as even just visually moving them away from inputs fields works. (see bug variant 3 above). So depending on your layout, e.g. if you have a sidebar with a search field which is moving in from the side of your page and overlaying the main content, consider not overlaying the main content but instead moving it to the side.

  3. Use 'display:none' on elements with touch event binding when not in use. This the only css property which seems to solve bug variant 3. 'visibility: hidden' had no effect in my tests. Elements with 'display:none' do not affect inputs elements anymore with this bug. In case you are building a one-pager, you should consider settings pages or 'touch bound elements' that are not in view to display none. This will prevent bug variant 3.

  4. Of course, the best thing is to avoid using iframe/object/embed tags to display other content as long as this bug exists.

like image 65
Seitenwerk Avatar answered Oct 08 '22 13:10

Seitenwerk