Click/Tap event not triggering in iframe on iOS devices
Asked Answered
M

1

3

I have an instance of an iframe that contains an element with a click handler. The iframe contains a video with a play button graphic overlaid with a click event attached to it. The click event triggers the video to play, hides itself and console.logs a message to say it's been triggered.

This functions perfectly on desktop browsers, and when i navigate directly to the iframe url on an iOS device. However, when the iframe is embedded the play button's click/tap event is not fired.

Here are links to my examples:

The direct link to the video page: (works as intended on iOS) http://www.newsryde.com/articlevideo/1085078/

The link to the page with the video iframed: (does not trigger click/tap event) http://www.newsryde.com/article/1085078/

the file/line number where the event is attached is in /js/jm/video-player.js ~ line 52 and looks like:

els.playButton.on('click tap', function(){
    console.log('tapped');
    els.playButton.fadeOut(100);
    els.videoPauseItems.fadeOut(100);
    jwplayer(container).play();
});

the embedded iframe version of the code not only doesn't trigger the video, but doesn't trigger the console.log or element fades. I can see when tapping on the play button that the element flicker with a super quick opacity/feedback state that i believe is browser related

strangely though, when i remove the play button element. and just let the user click directly on the <video> element. the video plays fine. i can understand if it was one way or the other (no clicks made it through, or just the video playing didnt trigger), but it's as if the entire playButton's click handler just gets ignored

NOTES: I MUST use an iframe for this content, as it is not guaranteed that its contents will be from the same domain as the parent page (similarly this prevents me from creating an external control to the iframe content)

Any help would be greatly appreciated. Thank you in advance

EDIT1: upon request i added a single tap/click bind to the 'N' (i know it's a small hit box, sorry) in the top right hand corner of the example links.

els.videoPauseItems.css('z-index', '600').on('click tap', function(){
    console.log('non play button tapped');
});

When this is tapped while in the iframe i get no console.log. but i do get the browser quick grey flash tap feedback. however when inspecting the element i can see that it has successfully applied the .css() adjustment. When tapped when viewing the link not in an iframe it successfully console.log's

Maffei answered 28/3, 2014 at 3:46 Comment(6)
Have you tried to just check this out with an external element to see if any of the calls are fired? Not the playBUtton. Just a simple link, to see if even a console.log is fired.Splotch
@EthanJWPlayer do you mean like another button with a click event attached that just console.logs? but isnt bound during the player initialisation?Maffei
@EthanJWPlayer added EDIT to main question and posted results.Maffei
Hm, so it looks like this issue is outside of the player, then, if just a simple console log is not working outside of the player itself on a basic button.Splotch
@EthanJWPlayer, yeah i had originally thought it was something to do with the player.. but it appears to be a deeper problem than that.. i will continue to see if i can come up with solutionsMaffei
Okay, please let me know what you find here.Splotch
H
8

It seems that someone prevents the default action of the normal touch events flow: touchstart - touchmove - click. Such that the click event is never called. Probably some other script does this by calling preventDefault() on the event object of touchstart or touchend events or by returning false from event listeners of these events.

To overcome this issue you can intercept user's "tap" before the event is prevented. For example by using touchstart event:

var ranOnce = false;
els.playButton.on('click tap touchstart', function() {
    // If both click and touchstart events are fired,
    // then make sure that this function isn't executed twice if click
    if (ranOnce) return;
    ranOnce = true;

    console.log('tapped');
    els.playButton.fadeOut(100);
    els.videoPauseItems.fadeOut(100);
    jwplayer(container).play();
});

I ran this code via Safari developer tools on my iPhone and the video plays as expected:

enter image description here

Hux answered 1/4, 2014 at 23:57 Comment(1)
Turns out iOS purposely interferes. When a mouse movement event results in a DOM change, iOS does not trigger click events. I've done my own testing to work around this issue, and the click events are ignored for exactly 100ms after the mouse event. quirksmode.org/blog/archives/2014/02/the_ios_event_c.htmlShould

© 2022 - 2024 — McMap. All rights reserved.