jQuery Toggle Between Functions Fn1 Fn2 Fn3 On Click

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












Is there a better way of toggling between different functions, on click events ? Something maybe that use "on" "off" methods or simpler alternative ?



(function($) 
$.fn.clickToggle = function(func1, func2, func3)
var funcs = [func1, func2, func3];
this.data('toggleclicked', 0);
this.click(function()
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 3;
);
return this;
;
(jQuery));

$('#b1').clickToggle(
function() alert('First handler');,
function() alert('Second handler');,
function() alert('Third handler');
);






share|improve this question



















  • I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
    – Barmar
    Jan 12 at 23:08










  • That will cause an infinite loop.
    – Barmar
    Jan 12 at 23:09
















up vote
0
down vote

favorite












Is there a better way of toggling between different functions, on click events ? Something maybe that use "on" "off" methods or simpler alternative ?



(function($) 
$.fn.clickToggle = function(func1, func2, func3)
var funcs = [func1, func2, func3];
this.data('toggleclicked', 0);
this.click(function()
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 3;
);
return this;
;
(jQuery));

$('#b1').clickToggle(
function() alert('First handler');,
function() alert('Second handler');,
function() alert('Third handler');
);






share|improve this question



















  • I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
    – Barmar
    Jan 12 at 23:08










  • That will cause an infinite loop.
    – Barmar
    Jan 12 at 23:09












up vote
0
down vote

favorite









up vote
0
down vote

favorite











Is there a better way of toggling between different functions, on click events ? Something maybe that use "on" "off" methods or simpler alternative ?



(function($) 
$.fn.clickToggle = function(func1, func2, func3)
var funcs = [func1, func2, func3];
this.data('toggleclicked', 0);
this.click(function()
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 3;
);
return this;
;
(jQuery));

$('#b1').clickToggle(
function() alert('First handler');,
function() alert('Second handler');,
function() alert('Third handler');
);






share|improve this question











Is there a better way of toggling between different functions, on click events ? Something maybe that use "on" "off" methods or simpler alternative ?



(function($) 
$.fn.clickToggle = function(func1, func2, func3)
var funcs = [func1, func2, func3];
this.data('toggleclicked', 0);
this.click(function()
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 3;
);
return this;
;
(jQuery));

$('#b1').clickToggle(
function() alert('First handler');,
function() alert('Second handler');,
function() alert('Third handler');
);








share|improve this question










share|improve this question




share|improve this question









asked Jan 6 at 14:31









skyisfalling

6




6











  • I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
    – Barmar
    Jan 12 at 23:08










  • That will cause an infinite loop.
    – Barmar
    Jan 12 at 23:09
















  • I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
    – Barmar
    Jan 12 at 23:08










  • That will cause an infinite loop.
    – Barmar
    Jan 12 at 23:09















I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
– Barmar
Jan 12 at 23:08




I think this is a good method. I think using .off() and .on() to change the handler won't work, because when the next handler is added with .on(), and the old handler returns, it will then run the next handler immediately.
– Barmar
Jan 12 at 23:08












That will cause an infinite loop.
– Barmar
Jan 12 at 23:09




That will cause an infinite loop.
– Barmar
Jan 12 at 23:09










1 Answer
1






active

oldest

votes

















up vote
1
down vote













Your general approach seems sound. But you shouldn't hard-code the number of handlers. Take the functions as a rest-arg, and use funcs.length in the modulo expression.



You can also use the argument to .data() to look up the named data element, rather than getting the whole data object.



$.fn.clickToggle = function(...funcs) 
this.data('toggleclicked', 0);
this.click(function()
var tc = $(this).data("toggleclicked");
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % funcs.length;
);
return this;
;


You might also want to special-case a single function and just bind it the normal way, and completely ignore the call if there are no functions.



$.fn.clickToggle = function(...funcs) 
switch (funcs.length)
case 0:
break;
case 1:
this.click(funcs[0]);
break;
default:
this.data('toggleclicked', 0);
this.click(function()
var tc = $(this).data("toggleclicked");
$.proxy(funcs[tc], this)();
$(this).data("toggleclicked", (tc + 1) % funcs.length);
);

return this;
;





share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184445%2fjquery-toggle-between-functions-fn1-fn2-fn3-on-click%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    Your general approach seems sound. But you shouldn't hard-code the number of handlers. Take the functions as a rest-arg, and use funcs.length in the modulo expression.



    You can also use the argument to .data() to look up the named data element, rather than getting the whole data object.



    $.fn.clickToggle = function(...funcs) 
    this.data('toggleclicked', 0);
    this.click(function()
    var tc = $(this).data("toggleclicked");
    $.proxy(funcs[tc], this)();
    data.toggleclicked = (tc + 1) % funcs.length;
    );
    return this;
    ;


    You might also want to special-case a single function and just bind it the normal way, and completely ignore the call if there are no functions.



    $.fn.clickToggle = function(...funcs) 
    switch (funcs.length)
    case 0:
    break;
    case 1:
    this.click(funcs[0]);
    break;
    default:
    this.data('toggleclicked', 0);
    this.click(function()
    var tc = $(this).data("toggleclicked");
    $.proxy(funcs[tc], this)();
    $(this).data("toggleclicked", (tc + 1) % funcs.length);
    );

    return this;
    ;





    share|improve this answer

























      up vote
      1
      down vote













      Your general approach seems sound. But you shouldn't hard-code the number of handlers. Take the functions as a rest-arg, and use funcs.length in the modulo expression.



      You can also use the argument to .data() to look up the named data element, rather than getting the whole data object.



      $.fn.clickToggle = function(...funcs) 
      this.data('toggleclicked', 0);
      this.click(function()
      var tc = $(this).data("toggleclicked");
      $.proxy(funcs[tc], this)();
      data.toggleclicked = (tc + 1) % funcs.length;
      );
      return this;
      ;


      You might also want to special-case a single function and just bind it the normal way, and completely ignore the call if there are no functions.



      $.fn.clickToggle = function(...funcs) 
      switch (funcs.length)
      case 0:
      break;
      case 1:
      this.click(funcs[0]);
      break;
      default:
      this.data('toggleclicked', 0);
      this.click(function()
      var tc = $(this).data("toggleclicked");
      $.proxy(funcs[tc], this)();
      $(this).data("toggleclicked", (tc + 1) % funcs.length);
      );

      return this;
      ;





      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        Your general approach seems sound. But you shouldn't hard-code the number of handlers. Take the functions as a rest-arg, and use funcs.length in the modulo expression.



        You can also use the argument to .data() to look up the named data element, rather than getting the whole data object.



        $.fn.clickToggle = function(...funcs) 
        this.data('toggleclicked', 0);
        this.click(function()
        var tc = $(this).data("toggleclicked");
        $.proxy(funcs[tc], this)();
        data.toggleclicked = (tc + 1) % funcs.length;
        );
        return this;
        ;


        You might also want to special-case a single function and just bind it the normal way, and completely ignore the call if there are no functions.



        $.fn.clickToggle = function(...funcs) 
        switch (funcs.length)
        case 0:
        break;
        case 1:
        this.click(funcs[0]);
        break;
        default:
        this.data('toggleclicked', 0);
        this.click(function()
        var tc = $(this).data("toggleclicked");
        $.proxy(funcs[tc], this)();
        $(this).data("toggleclicked", (tc + 1) % funcs.length);
        );

        return this;
        ;





        share|improve this answer













        Your general approach seems sound. But you shouldn't hard-code the number of handlers. Take the functions as a rest-arg, and use funcs.length in the modulo expression.



        You can also use the argument to .data() to look up the named data element, rather than getting the whole data object.



        $.fn.clickToggle = function(...funcs) 
        this.data('toggleclicked', 0);
        this.click(function()
        var tc = $(this).data("toggleclicked");
        $.proxy(funcs[tc], this)();
        data.toggleclicked = (tc + 1) % funcs.length;
        );
        return this;
        ;


        You might also want to special-case a single function and just bind it the normal way, and completely ignore the call if there are no functions.



        $.fn.clickToggle = function(...funcs) 
        switch (funcs.length)
        case 0:
        break;
        case 1:
        this.click(funcs[0]);
        break;
        default:
        this.data('toggleclicked', 0);
        this.click(function()
        var tc = $(this).data("toggleclicked");
        $.proxy(funcs[tc], this)();
        $(this).data("toggleclicked", (tc + 1) % funcs.length);
        );

        return this;
        ;






        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Jan 12 at 23:21









        Barmar

        27019




        27019






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f184445%2fjquery-toggle-between-functions-fn1-fn2-fn3-on-click%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation