简体   繁体   中英

Enable scrolling event when div is in viewport only once then reset when out of viewport

I'm trying to track an element every time it enters the viewport in Amplitude. Right now when an element is scrolled into view the jQuery detects the elements id, if it was scrolled up or down, and states that it is a scroll event. These items are display in Amplitude admin. The issue is when the div is in viewport the scroll event is fired for EVERY mouse scroll. So it creates a ton of events when only one is need per element in viewport. How do I fire the event only once but then reset it once its out of viewport again?

     function isScrolledIntoView(elem) {

            // set offset by 10%
            var offSet = jQuery(window).height()*0.1;
            // offset scrolltop
            var docViewTop = jQuery(window).scrollTop() + offSet;
            // set window height area to 80% 
            var windowSize = jQuery(window).height()*0.8;

            var docViewBottom = docViewTop + windowSize;

            var elemTop = jQuery(elem).offset().top;

            var elemBottom = elemTop + jQuery(elem).height();


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


        }
        var lastScrollTop = 0;
        jQuery(window).scroll(function (event) {

                // detects scroll direction.
                var st = jQuery(this).scrollTop();
                   if (st > lastScrollTop){
                     var action = 'ScrollDown';
                   } else {
                      var action = 'ScrollUp';
                   }
                   lastScrollTop = st;



                jQuery('.trackScrolling').each(function () {

                    // get element ID
                   var elementID = jQuery(this).attr("id");

                    var ScrollEvents = 'ScrollEvents';  

                  // if in viewport fire event
                    if (isScrolledIntoView(this) === true) {


                      gu_event(ScrollEvents, action, elementID);


                    } 


                });

        });

You'll need to create a boolean flag for each element to check if it is already in the viewport and add another if condition checking for it, something like this:

var elements = [];
var lastScrollTop = 0;

jQuery('.trackScrolling').each(function () {
    elements.push({
        "elem": this,
        "id": jQuery(this).attr("id")),
        "inView": false
    });
});

function isScrolledIntoView(elem) {
    // set offset by 10%
    var offSet = jQuery(window).height()*0.1;

    // offset scrolltop
    var docViewTop = jQuery(window).scrollTop() + offSet;

    // set window height area to 80% 
    var windowSize = jQuery(window).height()*0.8;

    var docViewBottom = docViewTop + windowSize;
    var elemTop = jQuery(elem).offset().top;
    var elemBottom = elemTop + jQuery(elem).height();

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

jQuery(window).scroll(function (event) {
    var action;

    // detects scroll direction.
    var st = jQuery(this).scrollTop();

    if (st > lastScrollTop){
       action = 'ScrollDown';
    } else {
       action = 'ScrollUp';
    }

    lastScrollTop = st;

    for (var i = 0; i < elements.length; i++) {
        var ScrollEvents = 'ScrollEvents';

        if (elements[i].inView === true && isScrolledIntoView(elements[i].elem) === true) {

            // do nothing in this case...
            console.log('Element ' + elements[i].id + ' is already in view!');

        } else if (isScrolledIntoView(elements[i].elem) === true) {

            // set the flag in this case and send the event
            elements[i].inView = true;
            gu_event(ScrollEvents, action, elements[i].id);

        } else if (isScrolledIntoView(elements[i].elem) === false) {

            // reset the flag in this case
            elements[i].inView = false;
        }
    }
});

Instead of your scroll function continually finding all of the .trackScrolling elements, I've stored a reference to them upfront - the ID of each and whether it's in the viewport are stored in an object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM