简体   繁体   English

当div在视口中时仅启用一次滚动事件,然后在视口外时重置滚动事件

[英]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. 我试图跟踪每次以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. 现在,当元素滚动到视图中时,jQuery会检测元素ID(如果元素是向上滚动还是向下滚动),并指出它是滚动事件。 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. 问题是,当div在视口中时,每次鼠标滚动都会触发滚动事件。 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: 您需要为每个元素创建一个布尔标志,以检查它是否已经在视口中,并添加另一个if条件检查它,如下所示:

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. 我没有在scroll功能中不断查找所有.trackScrolling元素,而是预先存储了对它们的引用-每个元素的ID以及它是否在视口中都存储在一个对象中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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