繁体   English   中英

当我向下滚动页面时,事件触发了几次

[英]Event fired several times when i scroll down the page

当用户向下滚动页面时,我尝试显示一些数据,但调用的ajax至少完成了2次,有时完成了4次。 反正有一次只能执行ajax调用吗? 谢谢。

   $(window).scroll(function () {
        if ($(document).height() <= $(window).scrollTop() + $(window).height()) {
                $.ajax({
                type : "POST",
                url : $('#AjaxMoreStatus').attr("data-url"),
                dataType : "HTML",
                beforeSend: function() {
                    $('.spinner').show();
                },
                complete: function() {
                    $('.spinner').hide();
                },
                success : function (data) {
                    $('#AjaxMoreStatus').append(data);
                }
            });
        }
    });

当您使用.scroll()事件并滚动window时,它将被多次触发。 这是预期的行为。 最好的方法是使用计时器( 500ms然后等待浏览器停止滚动:

var tmr = 0;
$(window).scroll(function () {
  clearTimeout(tmr);
  $('.spinner').show();
  tmr = setTimeout(function () {
    if ($(document).height() <= $(window).scrollTop() + $(window).height()) {
      $.ajax({
        type : "POST",
        url : $('#AjaxMoreStatus').attr("data-url"),
        dataType : "HTML",
        beforeSend: function() {
          $('.spinner').show();
        },
        complete: function() {
          $('.spinner').hide();
        },
        success : function (data) {
          $('#AjaxMoreStatus').append(data);
        }
      });
    }
  }, 500);
});

这还会将您的AJAX轮询保存到服务器太多次。 您也可以将beforeSend()的内容放在AJAX调用和计时器的顶部。

嗯,这是一个已知的问题,可以通过一种称为debouncing logic的技术来解决。

什么是反跳逻辑:它会返回一个函数,只要继续调用该函数就不会被触发。 该函数将在停止调用N毫秒后被调用。 如果通过了即时 ,则在前沿而不是尾随触发函数。


防弹跳逻辑:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
  var timeout;
  return function() {
     var context = this, args = arguments;
     var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
     };
     var callNow = immediate && !timeout;
     clearTimeout(timeout);
     timeout = setTimeout(later, wait);
     if (callNow) func.apply(context, args);
  };
};

//target code/callback to be called on scroll/resize event
function callback() {
    clearTimeout(tmr);
   $('.spinner').show();
   tmr = setTimeout(function () {
     if ($(document).height() <= $(window).scrollTop() + $(window).height())  {
      $.ajax({
        type : "POST",
        url : $('#AjaxMoreStatus').attr("data-url"),
        dataType : "HTML",
        beforeSend: function() {
          $('.spinner').show();
        },
        complete: function() {
          $('.spinner').hide();
        },
        success : function (data) {
          $('#AjaxMoreStatus').append(data);
        }
    });
  }
}

//registering callback function to debouncing logic
$(window).scroll(function () {
     debounce(callback, 250);
}

现在,使用debouncing逻辑,不仅可以解决当前的问题,而且可以不必担心用户何时停止滚动页面,从而可以调用目标函数,因为它可能会持续500毫秒甚至到1毫秒。秒

上面的代码是通用代码,因此您不必对脚本上的用户交互进行任何假设。

参考: https : //davidwalsh.name/javascript-debounce-function

暂无
暂无

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

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