clankill3r
clankill3r

Reputation: 9533

How to know when an iframe comes into view?

If I have a site that holds an iframe:

<html>

    <body>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <iframe src="http:/somelink.com/iframe.html"></iframe>
    </body>

</html>

Is it then possible for the iframe to know if it can be "seen"? This for example by knowing the top position of the iframe related to the top of the screen.

This is my test iframe: (all values are 0, no matter scroll pos of parent)

<html>
    <head>
        <script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
        <script type="text/javascript">

            $(document).ready(function() {
                console.log("ok");  

                check();

            });


            function check() {

                // position of parent
                var parentScrollTop = $(window.parent.document).scrollTop();
                console.log("parentScrollTop: "+parentScrollTop);

                // self position
                var bodyPosition = $("body").position().top;
                console.log("body position: "+bodyPosition);

                setInterval(check, 1000);
            }

        </script>

        <style type="text/css">
            body {
                background-color: red;
            }
        </style>
    </head>
    <body>

    </body>
</html>

I made an image to be more clear. enter image description here

I have to know from within the iframe if it's visible or not! So not from within the page that holds the iframe.

Upvotes: 9

Views: 4926

Answers (4)

dekajoo
dekajoo

Reputation: 2102

I know this is an old question but some new API from Chrome have been released that could answer your question on the latest versions of Chrome (22+)

The InteractionObserver you can find it here: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

There is a polyfill that is being developped (same repo) but it will not work from within the iframe afaik only if the script is on the parent webpage.

For other browsers their is some dark ways to do it based on timing attack, this article explains it pretty well: https://www.contextis.com/media/downloads/Pixel_Perfect_Timing_Attacks_with_HTML5_Whitepaper.pdf

Edit: Next Firefox version to come has the InteractionObserver feature activated by default now, Same for Edge !

Upvotes: 3

clankill3r
clankill3r

Reputation: 9533

This worked for me. It requires that the page holding the iframe has jQuery.

function isScrolledIntoParentView(elem) {


                var $elem = window.parent.$(elem);

                var docViewTop = $(window.parent).scrollTop();
                var docViewBottom = docViewTop + window.parent.innerHeight;

                var elemTop = $elem.offset().top;
                var elemBottom = elemTop + $elem.height();

                console.log("isScrolledIntoParentView");
                console.log($elem);
                console.log("docViewTop "+docViewTop);
                console.log("docViewBottom "+docViewBottom);
                console.log("elemTop "+elemTop);
                console.log("elemBottom "+elemBottom);

                return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
            }

Upvotes: 0

dayuloli
dayuloli

Reputation: 17001

This is a similar issue with detecting infinite scrolling - How do we know the 'Load more' button is visible?

As an extension to the above link, you can also write a function which will detect if any element is visible (on the y-axis) (copied over for reference):

function isScrolledIntoView(elem)
{
    var $elem = $(elem);
    var $window = $(window);

    var docViewTop = $window.scrollTop();
    var docViewBottom = docViewTop + $window.height();

    var elemTop = $elem.offset().top;
    var elemBottom = elemTop + $elem.height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Upvotes: 0

StudioTime
StudioTime

Reputation: 23959

Use this: https://github.com/customd/jquery-visible

Add an id to the iframe then you can use this:

if ($('#iframeID').visible(true)) {
  // The iframe is visible
} else {
  // The iframe is NOT visible
}

Upvotes: 0

Related Questions