19

I'm trying to embed HTML5 games in iframes to display in browser on mobile devices such as iPads and iPhones.

If you visit them directly on an iPad they work fine.

But if you embed them using an iframe then when you touch the game and then let go, the game pauses.

Is there a way to stop this iframe behaviour so that they behave as they should?

It seems like maybe focus is lost when you stop touching and it think's your vacant and pauses?

Example

Try the two example links below in the emulator and you will see the issue

The code I'm using (basic)

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Game</title>
</head>    
<body>

<div>
  <iframe src="http://static.tresensa.com/madcab/index.html?dst=A0000" frameborder="0" scrolling="no" width="960" height="536"></iframe>
</div>

</body>
</html>

What I've tried

css styling to change the interaction type

<div style="overflow:auto;-webkit-overflow-scrolling:touch;">
    <iframe src="" height="" height=""></iframe>
</div>

JS to prevent defaults

<script>
document.ontouchmove = function(e) {
    e.preventDefault();
};
</script>

... neither have helped

Dan
  • 11,914
  • 14
  • 49
  • 112
  • 1
    Have you seen these answers http://stackoverflow.com/questions/5267996/how-to-properly-display-an-iframe-in-mobile-safari and this one too http://stackoverflow.com/questions/19667785/iframe-and-mobile-safari-ipad-iphone – Sudarshan Kalebere Dec 16 '14 at 13:48

2 Answers2

6

Facing the same problem at the moment. It seems only Safari does it in that way on Google Chrome Samsung Galaxay S4 it works.

Update: I think this problem can't be solved from a website hosting the game. What I found out so far while going deeper into the material: If you add this into the code for example CSS:

body{
    -ms-touch-action: none;
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    }

or/and Javascript

document.addEventListener('ontouchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('ontouchmove', function(e) {e.preventDefault()}, false);

of the "iframed game" it will work and block this behavior (things like: touchmoves, touchscroll etc. everthing that makes the game losing focus). But everything which is in the iframe sticks to the rules of the code there and seems can't be blocked if we try to add this to the iframe-grid.

The only workaround I could think of is to overlay an absolute invisible div with an higher z-index and try to add the abilities to it. But I think the game won't respond at the touch anymore in this case. IDK...

Marc El
  • 63
  • 5
2

What to do:


You can add the following to the game page's HTML:

<body onload="init()">

or alternatively in JavaScript

document.addEventListener('load', init);

 

Add the following JS on the game page as well

window.init = function() {
  window.parent.frameRegister(window.frameElement.id);
}

 

In your container page, define frameRegister in JS:

var frame;
window.frameRegister = function(frameId) {
  frame = window.frames[frameId];
}

 

All this is doing is setting up a means of communication between the two frames. We'll be using this later in the next section to pass events appropriately between the top-level and destination frames.

Then we're going to force push those events to the appropriate element at the location in your child container.

 

On the parent document (your container for the iframe)

Add this JS

var touchEvents = ['start', 'move', 'enter', 'leave', 'cancel', 'leave']; // Make this whichever events you want to pass

for (i = 0, l = touchEvents.length; i<l; i++) {
  document.addEventLister('touch' + touchEvents[i], function(e) {
    e.preventDefault();
    frame.document.elementFromPoint(e.pageX, e.pageY);.dispatchEvent(e);
  }
}

Assumptions


  1. Your iframe is the same size as its containing element
  2. Your code is used only for mobile
    • If you're using it for the web (in an iframe) and somehow getting it to work in IE 8 or less, you'll need to use attachEvent and shim elementFromPoint accordingly.

Additional Considerations


If you're using jQuery

  • Touch events in jQuery using pageX/pageY
  • This answer is likely incomplete. More things will need to be done in order to ensure you're hitting the correct element.
    • e.g. If you're using any sort of overlay, CSS with pointer-events: none; on the overlay will need to be used.
Community
  • 1
  • 1
Josh Burgess
  • 9,327
  • 33
  • 46