当元素变得可见时,jQuery滚动函数会触发一次

时间:2016-05-15 16:09:29

标签: javascript jquery html scroll onscroll

大家好我在这个脚本上使用滚动功能,但每次用户滚动时都会触发。我希望它只在用户向下滚动到#ror时触发一次。我尝试使用fired变量来检查它是否已被触发,但似乎没有用。我知道有些人之前已经回答了这个问题,但这是我得到解决方案的地方,并且无法让它只工作一次。有人认为他们可以帮忙吗?

$( window  ).scroll(function() {
var fired = 0;
    console.log(fired);
    if(fired == 0){
    $('#ror').html('');
    $('#ror').goalProgress({
     goalAmount: 100,
     currentAmount: 75,
     textBefore: 'progress bar',
     textAfter: '',
     offset: 10,
     });
     fired=1;   
   }
});

3 个答案:

答案 0 :(得分:2)

您需要将已触发的变量移动到滚动功能之外。 正如您现在所做的那样,每次滚动事件被触发时,您都会重新初始化fired变量并将其设置为0

var fired = 0;
$(window).scroll(function() {
    console.log(fired);
    if(fired == 0){
    $('#ror').html('');
    $('#ror').goalProgress({
     goalAmount: 100,
     currentAmount: 75,
     textBefore: 'progress bar',
     textAfter: '',
     offset: 10,
     });
     fired=1;   
   }
});

答案 1 :(得分:2)

要检测给定#target滚动到视图的位置,您可以查看它的顶部位置,并检查该位置是否已在视口内。

$('#target').offset().top - $(window).outerHeight() > $(window).scrollTop();

等式的左边部分是常数(只要你不移动任何东西,或改变视口的大小)。因此,将它移到事件处理函数之外是明智的。您需要记住滚动事件相当昂贵,因为滚动时它会不断触发,并且浏览器已经非常忙于渲染视口。

完成工作后,您可以删除事件处理程序。

$(window).off(event);

所以你的最终代码看起来像这样:

var triggerAtY = $('#target').offset().top - $(window).outerHeight();

$(window).scroll(function(event) {
  // #target not yet in view
  if (triggerAtY > $(window).scrollTop()) {
    return;
  }

  // run your task

  // remove this event handler
  $(this).off(event);
}); 

看看演示:https://jsfiddle.net/6whnfa02/1/

文档:

答案 2 :(得分:1)

$(window).scroll(function(event) {
    var eT = $('#ror').offset().top,
    wH = $(this).height(),
    wSt = $(this).scrollTop();
    if(wSt > (eT-wH)) {
      alert('you have scrolled to the ror!');
      //detach scroll event handler, as we dont want it to fire again
      $(this).off(event);
    }
}

上面的代码检查用户是否已向下滚动到元素。如果是,请提醒某些内容并分离window的滚动事件处理程序。您可以参考jquery documentation来查看offset,height和scrollTop的含义。

现在,当 @Pevera 指针输出时,将事件处理程序附加到窗口滚动是很昂贵的,你应该知道这一点。如果你在滚动回调中有一些繁重的代码执行,它将阻碍滚动页面。因此,如果必须将处理程序附加到窗口滚动,请在超时回调中运行滚动回调代码。它确保在某些延迟后运行滚动回调代码,这有助于更好地滚动页面。用超时重写上面的代码将如下所示:

var timeout = null;
$(window).scroll(function (event) {
    if (!timeout) {
        // set a timeout to run after 250ms
        timeout = setTimeout(function () {
            clearTimeout(timeout);
            timeout = null;
            var eT = $('#ror').offset().top,
            wH = $(this).height(),
            wSt = $(this).scrollTop();
            if (wSt > (eT-wH)){
              alert('you have scrolled to the ror!');
              //detach scroll event handler, as we dont want it to fire again
              $(this).off(event);
            }
        }, 250);
    }
});

每次用户滚动页面时,超时设置为在(至少)250ms之后运行。在超时回调中,我们删除此超时处理程序并检查用户是否已滚动到该元素。如果是,我们会发出警告并分离窗口的滚动处理程序,以便它不会再次运行。

请参阅此FIDDLE以获得更好的理解。

有关此stackoverflow post和John Resig blog post的更多信息。