Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fire Javascript Event When a DIV is in View

Is it possible to fire a specific javascript event when a certain DIV comes into view on the page?

Say, for example, I have a very large page, like 2500x2500 and I have a 40x40 div that sits at position 1980x1250. The div is not necessarily manually positioned, it could be there due to the content pushing it there. Now, is it possible to run a function when the user scrolls to a point where the div becomes visible?

like image 567
Russ Bradberry Avatar asked Jan 29 '10 00:01

Russ Bradberry


People also ask

What type of event occurs when a button is clicked?

The onclick event occurs when the user clicks on an element.

How do event listeners work in JavaScript?

Event listeners are called only when the event happens in the context of the object they are registered on. That example attaches a handler to the button node. Clicks on the button cause that handler to run, but clicks on the rest of the document do not. Giving a node an onclick attribute has a similar effect.

What is click event in JavaScript?

An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.

How do you find the ID of the view by which the event method is triggered?

You can use event.target.id in event handler to get id of element that fired an event.


Video Answer


1 Answers

Not automatically. You would have to catch scroll events and check for it being in view each time by comparing the co-ordinates of the div rectangle with the visible page rectangle.

Here's a minimal example.

<div id="importantdiv">hello</div>

<script type="text/javascript">
    function VisibilityMonitor(element, showfn, hidefn) {
        var isshown= false;
        function check() {
            if (rectsIntersect(getPageRect(), getElementRect(element)) !== isshown) {
                isshown= !isshown;
                isshown? showfn() : hidefn();
            }
        };
        window.onscroll=window.onresize= check;
        check();
    }

    function getPageRect() {
        var isquirks= document.compatMode!=='BackCompat';
        var page= isquirks? document.documentElement : document.body;
        var x= page.scrollLeft;
        var y= page.scrollTop;
        var w= 'innerWidth' in window? window.innerWidth : page.clientWidth;
        var h= 'innerHeight' in window? window.innerHeight : page.clientHeight;
        return [x, y, x+w, y+h];
    }

    function getElementRect(element) {
        var x= 0, y= 0;
        var w= element.offsetWidth, h= element.offsetHeight;
        while (element.offsetParent!==null) {
            x+= element.offsetLeft;
            y+= element.offsetTop;
            element= element.offsetParent;
        }
        return [x, y, x+w, y+h];
    }

    function rectsIntersect(a, b) {
        return a[0]<b[2] && a[2]>b[0] && a[1]<b[3] && a[3]>b[1];
    }

    VisibilityMonitor(
        document.getElementById('importantdiv'),
        function() {
            alert('div in view!');
        },
        function() {
            alert('div gone away!');
        }
    );
</script>

You could improve this by:

  • making it catch onscroll on all ancestors that have overflow scroll or auto and adjusting the top/left co-ords for their scroll positions
  • detecting overflow scroll, auto and hidden cropping putting the div off-screen
  • using addEventListener/attachEvent to allow multiple VisibilityMonitors and other things using the resize/scroll events
  • some compatibility hacks to getElementRect to make the co-ords more accurate in some cases, and some event unbinding to avoid IE6-7 memory leaks, if you really need to.
like image 158
bobince Avatar answered Oct 02 '22 15:10

bobince