JS-取消委托事件的反跳 [英] JS - Debounce a delegated event

查看:56
本文介绍了JS-取消委托事件的反跳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看 JS代码(这里也是代码段):

 //debounce function by davidwalsh: https://davidwalsh.name/javascript-debounce-function
//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);
  };
};
$(document).on('click', '#foo-one, #bar-one', debounce(function(e) {
  $('#counter-one').append('<span>1</span>');
}, 350));
$('#foo-two').click(debounce(function(e) {
  $('#counter-two').append('<span>2</span>');
}, 350));
$('#bar-two').click(debounce(function(e) {
  $('#counter-two').append('<span>2</span>');
}, 350));
$(document).on('click', '#foo-three, #bar-three', function(e) {
  var $this = $(this);
  if ($this.is('#foo-three')) {
    //should happen immediately
    $('#counter-three').append('<span>3</span>');
  }
  if ($this.is('#bar-three')) {
    //should debounce
    debounce(function() {
      $('#counter-three').append('<span>3</span>');
    }, 350);
  }
}); 

 div > div {
  height: 64px;
  width: 64px;
  border: 1px solid black;
  display: inline-block;
}
#counter-one,
#counter-two,
#counter-three {
  background-color: red;
} 

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div>
  <div id="foo-one">Foo1</div>
  <div id="bar-one">Bar1</div>
  <div id="counter-one"><span>Counter1</span>
  </div>
</div>
<div>
  <div id="foo-two">Foo2</div>
  <div id="bar-two">Bar2</div>
  <div id="counter-two"><span>Counter2</span>
  </div>
</div>
<div>
  <div id="foo-three">Foo3</div>
  <div id="bar-three">Bar3</div>
  <div id="counter-three"><span>Counter3</span>
  </div>
</div> 

仅在单击某个项目时,我试图将去抖器添加到委派的Click事件中.如您所见,我展示了两种反跳代码的方法(如上所述).第一个是在委托事件上.如果所有要委派的元素都应取消其点击,则此方法有效.第二种方法是使用未授权的点击,然后委派每个功能.

第三种方法是代码停止工作的地方.在这种情况下,单击处理程序是委派的;但是,只有委派的第二个元素才应反跳.我使用$(this).is()来区分两个元素之间的区别.现在,如果您单独调用debouncer函数(tku David Walsh ),它将无法正常工作...

我需要委派事件,因为它需要更新/刷新,并且按照jQuery的问题):

委派的事件的优势在于,它们可以处理以后在后代添加到文档中的后代元素中的事件.通过选择保证在附加委托事件处理程序时会出现的元素,您可以使用委托事件来避免频繁附加和删除事件处理程序的需要.

有人知道我如何在委托事件中的两个元素之一上实现反跳效果,而在触发时不使另一个元素反跳吗?

解决方案

debounce()返回必须多次调用的函数,这些调用将被去抖动. debounce()调用创建的每个函数都分别执行此操作.另请参见有人可以解释反跳"吗? __debounce的作用是什么?.

因此,您必须通过多个debounce()调用(每个元素一个)来创建多个函数,然后分别调用它们.

var functions = {
  "foo-three": function() {
    //should happen immediately
    $('#counter-three').append('<span>3</span>');
  },
  "bar-three": debounce(function() {
    $('#counter-three').append('<span>3</span>');
  }, 350)
};
$(document).on('click', '#foo-three, #bar-three', function(e) {
  functions[this.id].call(this, e);
});

在这种情况下,委派活动不会给您带来多少好处.

Take a look at this JS code (here's also a snippet):

//debounce function by davidwalsh: https://davidwalsh.name/javascript-debounce-function
//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);
  };
};
$(document).on('click', '#foo-one, #bar-one', debounce(function(e) {
  $('#counter-one').append('<span>1</span>');
}, 350));
$('#foo-two').click(debounce(function(e) {
  $('#counter-two').append('<span>2</span>');
}, 350));
$('#bar-two').click(debounce(function(e) {
  $('#counter-two').append('<span>2</span>');
}, 350));
$(document).on('click', '#foo-three, #bar-three', function(e) {
  var $this = $(this);
  if ($this.is('#foo-three')) {
    //should happen immediately
    $('#counter-three').append('<span>3</span>');
  }
  if ($this.is('#bar-three')) {
    //should debounce
    debounce(function() {
      $('#counter-three').append('<span>3</span>');
    }, 350);
  }
});

div > div {
  height: 64px;
  width: 64px;
  border: 1px solid black;
  display: inline-block;
}
#counter-one,
#counter-two,
#counter-three {
  background-color: red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div>
  <div id="foo-one">Foo1</div>
  <div id="bar-one">Bar1</div>
  <div id="counter-one"><span>Counter1</span>
  </div>
</div>
<div>
  <div id="foo-two">Foo2</div>
  <div id="bar-two">Bar2</div>
  <div id="counter-two"><span>Counter2</span>
  </div>
</div>
<div>
  <div id="foo-three">Foo3</div>
  <div id="bar-three">Bar3</div>
  <div id="counter-three"><span>Counter3</span>
  </div>
</div>

I am trying to add a debouncer to a delegated click event, only when a certain item is clicked. As you can see, I show two ways of debouncing code (above). The first is on a delegated event. It works if all of them elements being delegated should have their clicks debounced. The second way is by using undelegated clicks, and each function is delegated.

The third way is where the code stops working. In this instance, the click handler is delegated; however, only the second element delegated should debounce. I use $(this).is() to tell the difference between the two elements. Now, if you call the debouncer function (tku David Walsh) by itself, it does not work...

I need the event to be delegated as it needs to be updated/refreshed and per jQuery's docs (also, this question):

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

Does anyone know how I can accomplish a debouncing effect on one of two elements in a delegated event, while leaving the other one to not debounce when triggered?

解决方案

debounce() returns a function that you have to call multiple times, and those calls will be debounced. Each function created by a debounce() call does this separately. See also Can someone explain the "debounce" function in Javascript or What does _.debounce do?.

So you have to create multiple functions via multiple debounce() calls, one per element, and call them separately.

var functions = {
  "foo-three": function() {
    //should happen immediately
    $('#counter-three').append('<span>3</span>');
  },
  "bar-three": debounce(function() {
    $('#counter-three').append('<span>3</span>');
  }, 350)
};
$(document).on('click', '#foo-three, #bar-three', function(e) {
  functions[this.id].call(this, e);
});

Delegating events doesn't buy you much in this scenario.

这篇关于JS-取消委托事件的反跳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆