Wednesday, May 23, 2018

Ipad Safari - Can't scroll page if scrolling inside iframe

Leave a Comment

Is it possible to continue scrolling through a webpage even if you are touching inside an iframe? This problem only happens with iOS devices and I couldn't find any solutions for this!

My current page contains an iframe in the middle with width:95% and about 500px height, so when I reach the iframe I can't scroll any more (unless I touch very close to the sides).

Thanks

2 Answers

Answers 1

In my case, I had full access to the iframe and was dynamically inserting its content. Still, none of the solutions suggested by Brandon S worked. My solution:

  • Create a transparent div overlaying the iframe.
  • Capture any click events on the overlay and replicate them within the iframe (to allow the user to click on links/buttons)

This works because the overlaying div is part of the outer document, making it respond to touch/click events normally, and prevents the user from directly interacting with the iframe content.


Html Template:

<div style="position: relative;">     <div         style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; opacity: 0;"         ng-click="$ctrl.handleOverlayClick($event)"     ></div> </div> 

Controller (AngularJS component)

...  constructor ($document, $element) {   this.iframe = $document[0].createElement('iframe');   this.iframe.width = '100%';   this.iframe.height = '100';   this.iframe.sandbox = 'allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation';   const element = $element[0].children.item(0);   element.appendChild(this.iframe);   this.contentDocument = this.iframe.contentDocument; }  handleOverlayClick ($event) {   // Overlay element is an invisible layer on top of the iframe. We use this to   // capture scroll events which would be in the iframe (which don't work properly on iPad Safari)   // When a click is detected, we propigate that through to the iframe so the user can click on links   const rect = $event.target.getBoundingClientRect();   const x = $event.clientX - rect.left; // x position within the iframe   const y = $event.clientY - rect.top;  // y position within the iframe    // triggering click on underlaying element   const clickedElement = this.contentDocument.elementFromPoint(x, y);   clickedElement && clickedElement.click(); } 

Answers 2

It sounds like the iframe is receiving the user's scroll event, instead of the page. This can happen when part of the iframe's content doesn't fit within the size of the iframe element.

A solution to this problem is to stop the iframe from ever trying to scroll. There are few ways to accomplish this:

  1. In iframe's HTML, add this CSS:
     html, body {         overflow: hidden     }  
  1. If you don't have access to the iframe's HTML (because maybe the iframe is loading a 3rd party's content), you can put a wrapper div around the iframe and disable scrolling that way. Add this to the parent page HTML:

    <div style="overflow: hidden"><iframe src="example.com"></iframe></div>

  2. You can add this to the parent page HTML CSS to make browser use momentum so that ends up scrolling past the bottom of the iframe and then scrolls the page:

    *{         -webkit-overflow-scrolling: touch     }  
  1. Add the legacy "scrolling" attribute to the iframe to stop the iframe from trying to scroll:

    <iframe src="example.com" scrolling="no"></iframe>

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment