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

时间:2017-08-31 19:06:22

标签: javascript jquery

我试图在每次进入Amplitude中的视口时跟踪一个元素。现在当一个元素滚动到视图中时,jQuery会检测元素id,如果它是向上或向下滚动,并声明它是一个滚动事件。这些项目显示在Amplitude管理员中。问题是当div在视口中时,每次鼠标滚动都会触发滚动事件。因此,当视口中每个元素只需要一个时,它会创建大量事件。如何仅触发一次事件,然后再次将其重置出视口?

     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);


                    } 


                });

        });

1 个答案:

答案 0 :(得分:0)

您需要为每个元素创建一个布尔标志,以检查它是否已经在视口中并添加另一个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;
        }
    }
});

而不是scroll函数不断查找所有.trackScrolling元素,我已经预先存储了对它们的引用 - 每个元素的ID以及它是否在视口中存储在一个对象中。