简体   繁体   中英

jQuery : fire callback only once

How to tell jQuery to fire a callback function only once ?

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

I want the callback_function to be called on "ready", on "turbolinks:load", but not twice if both events occurs on the same page.

Edit : I'm aware of the jQuery one() function, that doesn't answer the question actually. According to the jQuery docs, "The handler is executed at most once per element per event type." I want the reverse : the handler to be executed once for all event types.

You can unbind a callback by using jQuery.off and using a counter for the maximum amount of repetitions. With .one the callback is executed once for each event, which is undesirable

 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> 

You can also make a helper function for managing these limited-life callbacks

 //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> 

And here is the same thing in a curried form

 //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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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