jQuery:仅触发一次回调

时间:2018-09-23 13:42:00

标签: javascript jquery ruby-on-rails ruby-on-rails-5

如何告诉jQuery仅触发一次回调函数?

$(document).on('ready turbolinks:load', function callback_function() {
    console.log('callback function') // fired twice, on 'ready' and 'turbolinks:load' events
});

我希望在“就绪”,“ turbolinks:load”上调用callback_function,但如果两个事件都在同一页面上发生,则不要两次。

编辑:我知道jQuery one()函数,实际上并不能回答问题。根据jQuery的文档,“处理程序每​​个事件类型的每个元素最多执行一次。”我希望相反:所有事件类型的处理程序都执行一次。

1 个答案:

答案 0 :(得分:1)

您可以通过使用jQuery.off并使用计数器来获得最大重复次数来取消绑定回调。使用.one,每个事件都会执行一次回调,这是不希望的

let count = 0;
function callbackWithCounter(event) {
  if (count++ >= 1){
    $(this).off(event)
    return;
  }
  console.log("button clicked " + count);
}

function simpleCallback(event) {
  console.log("button clicked");
}

$('#clickme').one("click mousedown mouseup", simpleCallback);
$('#clickme-two').on("click mousedown mouseup", callbackWithCounter);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='clickme'>Click me using .one</button><br/>
<button id='clickme-two'>Click me with a counter and .off</button>

您还可以创建一个辅助功能来管理这些寿命有限的回调

//a wrapper that will ensure the callback "self-destructs" and will be unbound correctly
function makeSelfDestructingEventCallback(maxExecutions, callback) {
  let count = 0;
  
  return function(event) {
    if (count++ >= maxExecutions){
      $(this).off(event)
      return;
    }
    //pass any normal arguments down to the wrapped callback
    return callback.apply(this, arguments);
  }
}

function callback(event) {
  console.log("button clicked");
}

$('#clickme').on("click mousedown mouseup", makeSelfDestructingEventCallback(1, callback));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='clickme'>Click me</button>

这是咖喱形式的同一件事

//a curried wrapper that will ensure the callback "self-destructs" and will be unbound correctly
function makeSelfDestructingEventCallback(maxExecutions) {
  return function(callback) {
    let count = 0;
    return function(event) {
      if (count++ >= maxExecutions){
        $(this).off(event)
        return;
      }
      //pass any normal arguments down to the wrapped callback
      return callback.apply(this, arguments);
    }
  }
  
}

function callback(event) {
  console.log("button clicked");
}

let one = makeSelfDestructingEventCallback(1);
let two = makeSelfDestructingEventCallback(2);

$('#clickme').on("click mousedown mouseup", one(callback));
$('#clickme-two').on("click mousedown mouseup", two(callback));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='clickme'>Click me - single execution</button><br/>
<button id='clickme-two'>Click me - executes twice</button>