Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to properly display an iFrame in mobile safari

I'm trying to display an iframe in my mobile web application, but I'm having trouble restricting the size of the iframe to the dimensions of the iPhone screen. The height and width attributes on the iframe element seem to have no effect, strangely. Surrounding it with a div manages to constrain it, but then I'm unable to scroll within the iframe.

Has anyone tackled iframes in mobile safari before? Any ideas where to start?

like image 934
Matt Diamond Avatar asked Mar 11 '11 01:03

Matt Diamond


People also ask

Does Safari support iframes?

See full reference on MDN Web Docs. 1 Safari has a bug that prevents iframes from loading if the iframe element was hidden when added to the page.

Why iframe is not working in Safari?

Why Safari doesn't allow to store cookie for iFrame? Answer: A: Answer: A: Try going to Safari/Preferences/Privacy and uncheck Prevent cross-site tracking.

Does iframe work on iPad?

iframes used to be scrollable on the iPad using two fingers. This functionality was removed in an update a few months ago. iframes don't respect overflow on iPad, and require an additional container surrounding the iframe with overflow:hidden.


2 Answers

Yeah, you can't constrain the iframe itself with height and width. You should put a div around it. If you control the content in the iframe, you can put some JS within the iframe content that will tell the parent to scroll the div when the touch event is received.

like this:

The JS:

setTimeout(function () { var startY = 0; var startX = 0; var b = document.body; b.addEventListener('touchstart', function (event) {     parent.window.scrollTo(0, 1);     startY = event.targetTouches[0].pageY;     startX = event.targetTouches[0].pageX; }); b.addEventListener('touchmove', function (event) {     event.preventDefault();     var posy = event.targetTouches[0].pageY;     var h = parent.document.getElementById("scroller");     var sty = h.scrollTop;      var posx = event.targetTouches[0].pageX;     var stx = h.scrollLeft;     h.scrollTop = sty - (posy - startY);     h.scrollLeft = stx - (posx - startX);     startY = posy;     startX = posx; }); }, 1000); 

The HTML:

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;"> <iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="url" /> </div> 

If you don't control the iframe content, you can use an overlay over the iframe in a similar manner, but then you can't interact with the iframe contents other than to scroll it - so you can't, for example, click links in the iframe.

It used to be that you could use two fingers to scroll within an iframe, but that doesn't work anymore.

Update: iOS 6 broke this solution for us. I've been attempting to get a new fix for it, but nothing has worked yet. In addition, it is no longer possible to debug javascript on the device since they introduced Remote Web Inspector, which requires a Mac to use.

like image 104
Case Avatar answered Oct 03 '22 10:10

Case


If the iFrame content is not yours then the solution below will not work.

With Android all you need to do is to surround the iframe with a DIV and set the height on the div to document.documentElement.clientHeight. IOS, however, is a different animal. Although I have not yet tried Sharon's solution it does seem like a good solution. I did find a simpler solution but it only works with IOS 5.+.

Surround your iframe element with a DIV (lets call it scroller), set the height of the DIV and make sure that the new DIV has the following styling:

$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'}); 

This alone will work but you will notice that in most implementations the content in the iframe goes blank when scrolling and is basically rendered useless. My understanding is that this behavior has been reported as a bug to Apple as early as iOS 5.0. To get around that problem, find the body element in the iframe and add -webkit-transform', 'translate3d(0, 0, 0) like so:

$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)'); 

If your app or iframe is heavy on memory usage you might get a hitchy scroll for which you might need to use Sharon's solution.

like image 41
Tmac Avatar answered Oct 03 '22 08:10

Tmac