3

I have an iframe that runs on sites (with a different domain). Can I know within the iframe if it is viable to the user or if the page that this iframe "live in" is active or not. Thanks.

Alon Ashkenazi
  • 1,223
  • 4
  • 21
  • 29
  • 1
    You could check if the iframe is clickable. For example `document.elementFromPoint(0,0)` returns `null` if that pixel is not visible. Though it also returns `null` if the iframe was only scrolled away from the screen... – Teemu Nov 12 '12 at 21:12
  • It's sound like a good direction to look at, but document.elementFromPoint(0,0) return the tag in all scenarios that I checked (the iframe scrooled away, the page isn;t in focus,..), can you please be more specific? – Alon Ashkenazi Nov 13 '12 at 11:16
  • I made a quicktest in IE9, FF, Chrome and Opera, and only with `display: none/block` when `window.onload` was fired in frame page. IE and Chrome returned exactly what I expected (`null/HTMLElement`). FF gave an error when `none`, only Opera returned always a `HTMLElement`. Unfortenately I can't test cross-domain, locally only. I didn't test scrolling, that was rather a guess on basis on my previous experience of `elementFromPoint()`. Notice, that this check should be done in `iframe`, not in any main page. – Teemu Nov 13 '12 at 12:24
  • 2
    It seems I've wasted your time, sorry for that. This actually works reliable only in IE. Other browsers seem to find the element even when it is offscreen, and also when `visibility:hidden` is set. And Opera, it always finds the element :(. Identical behavior with IE is described in https://developer.mozilla.org/en-US/docs/DOM/document.elementFromPoint , but obviously this is not true. – Teemu Nov 13 '12 at 15:58

2 Answers2

3

This is actually not possible, because you are not able to access the main page that embeds the frame from the frame itself, if you are on a different domain / port / scheme.

If your iframe is on the same domain && port && scheme, you could do this:

<html>
<body>
    <iframe src="frame.htm" id="myframe" style="display:block"></iframe>
</body>
</html>

And the frame.htm:

<script>
    var is_hidden = parent.document.getElementById("myframe").style.display == "none";
    alert(is_hidden ? "I am hidden" : "I am visible");
</script>

Update Overlooked the "from a different domain" - part of the question, updated the post accordingly.

David Müller
  • 5,291
  • 2
  • 29
  • 33
  • 1
    The question says *with a different domain*, so that that will get a permission error from the [Same Origin Policy](http://en.wikipedia.org/wiki/Same_origin_policy). – Quentin Nov 12 '12 at 20:36
  • `display: none` and `display: block` will both evaluate to `true`. – jbabey Nov 12 '12 at 20:39
  • Forgot, to add `== "none"` to the end, added it. Thanks for pointing out. – David Müller Nov 12 '12 at 20:40
  • http://stackoverflow.com/questions/2161388/iframe-function-calling-from-iframe-to-parent-page-javascript-function – A.M. D. Nov 12 '12 at 20:40
1

You should check out the Intersection Observer API. I was able to get it to work for two different domains.

Something like this worked for me:

function handleIntersect(entries, observer) {
  console.log('intersecting', entries[0].isIntersecting, 'visible', entries[0].isVisible);
}

let observer;

let options = {
  root: null,
  rootMargin: "0px",
  threshold: [0.5]
};

observer = new IntersectionObserver(handleIntersect, options);
// The DOM element here should be a div that captures the whole content of the iframe.
observer.observe(DOM_ELEMENT);
Siul
  • 109
  • 1
  • 7
  • You forgot to add the `trackVisibility: true` and `delay: 100 //100 is minimum` options: Otherwise `entries[0].isVisible` will always return false. Also, I believe you can use it to observe the iframe Element itself. (Only tested it on webconsole.) – bobajeff Jun 17 '21 at 02:19