JQuery click / switch between two functions

I am looking for a way to start two separate operations / functions / "code blocks" when something is clicked, and then a completely different block when the same click again. I put it together. I was wondering if there was a more efficient / elegant way. I know about jQuery . Toggle () , but that sucks.

Work here: http://jsfiddle.net/reggi/FcvaD/1/

var count = 0; $("#time").click(function() { count++; //even odd click detect var isEven = function(someNumber) { return (someNumber % 2 === 0) ? true : false; }; // on odd clicks do this if (isEven(count) === false) { $(this).animate({ width: "260px" }, 1500); } // on even clicks do this else if (isEven(count) === true) { $(this).animate({ width: "30px" }, 1500); } }); 
+69
javascript jquery
Feb 06 2018-11-11T00:
source share
9 answers

jQuery has two methods called .toggle() . the other [docs] does exactly what you want for click events.

Note. . Apparently, at least with jQuery 1.7 , this version of .toggle deprecated , probably for this very reason, namely that there are two versions. Using .toggle to change the visibility of elements is a more common use. This method has been removed in jQuery 1.9 .

The following is an example of how you can implement the same functionality as the plugin (but probably gives the same problems as the built-in version (see the last paragraph in the documentation).




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

Demo

(Disclaimer: I'm not saying this is the best implementation! I'm sure this can be improved in terms of performance)

And then name it with:

 $('#test').clickToggle(function() { $(this).animate({ width: "260px" }, 1500); }, function() { $(this).animate({ width: "30px" }, 1500); }); 

Update 2:

In the meantime, I created the right plugin for this. It accepts an arbitrary number of functions and can be used for any event. It can be found on GitHub .

+64
Feb 06 2018-11-11T00:
source share

Demo

.one () .

I answer very late, but I think this is the shortest code and can help.

 function handler1() { alert('First handler: ' + $(this).text()); $(this).one("click", handler2); } function handler2() { alert('Second handler: ' + $(this).text()); $(this).one("click", handler1); } $("div").one("click", handler1); 

DEMO with Op Code

 function handler1() { $(this).animate({ width: "260px" }, 1500); $(this).one("click", handler2); } function handler2() { $(this).animate({ width: "30px" }, 1500); $(this).one("click", handler1); } $("#time").one("click", handler1); 
+58
Aug 17 '13 at 9:52 on
source share

Micro jQuery plugin

If you want to create your own clickToggle jQuery method , you can do it like this:

 jQuery.fn.clickToggle = function(a, b) { return this.on("click", function(ev) { [b, a][this.$_io ^= 1].call(this, ev) }) }; // TEST: $('button').clickToggle(function(ev) { $(this).text("B"); }, function(ev) { $(this).text("A"); }); 
 <button>A</button> <button>A</button> <button>A</button> <script src="//code.jquery.com/jquery-3.3.1.min.js"></script> 



Simple Toggler Features

Live demo

 function a(){ console.log('a'); } function b(){ console.log('b'); } $("selector").click(function() { return (this.tog = !this.tog) ? a() : b(); }); 

If you want it to be even shorter (why not?), You can use the Bitwise XOR * Docs operator , for example:
Demo

  return (this.tog^=1) ? a() : b(); 

All this.
The trick is to set the tog property for this boolean object and toggle it using negation ( tog = !tog )
and put the necessary function calls in the conditional statement ?:





In the example, OP (even with multiple elements) might look like this:

 function a(el){ $(el).animate({width: 260}, 1500); } function b(el){ $(el).animate({width: 30}, 1500); } $("selector").click(function() { var el = this; return (el.t = !el.t) ? a(el) : b(el); }); 

ALSO: You can also store-switches like:
DEMO :

 $("selector").click(function() { $(this).animate({width: (this.tog ^= 1) ? 260 : 30 }); }); 

but it was not an exact request from the OP, because it is looking for a way to have two separate operations/functions




Using Array.prototype.reverse :

Note : this will not store the current state of Toggle, but simply invert the positions of our functions in the array (it uses ...)

You just save your functions a, b inside the array, by clicking you just change the order of the array and execute the function array[1] :

Live demo

 function a(){ console.log("a"); } function b(){ console.log("b"); } var ab = [a,b]; $("selector").click(function(){ ab.reverse()[1](); // Reverse and Execute! // >> "a","b","a","b"... }); 



SOME MASHUP!

JQuery demo
JavaScript DEMO

Create a beautiful toggleAB() function that will contain your two functions, put them in an array , and at the end of the array you simply execute the function [ 0//1 ] accordingly, depending on the tog property that was passed to the function from this link:

 function toggleAB(){ var el = this; // 'this' is the "button" Element Obj reference' return [ function() { console.log("b"); }, function() { console.log("a"); } ][el.tog^=1](); } $("selector").click( toggleAB ); 
+45
Feb 03 '14 at 5:42
source share

I would do something similar for the code you showed if all you have to do is switch the value:

 var oddClick = true; $("#time").click(function() { $(this).animate({ width: oddClick ? 260 : 30 },1500); oddClick = !oddClick; }); 
+24
Feb 06 2018-11-11T00:
source share

I used this to create the effect of switching between two functions.

 var x = false; $(element).on('click', function(){ if (!x){ //function x = true; } else { //function x = false; } }); 
+14
Mar 04 '13 at 6:05
source share

I do not think you should implement the toggle method since there is a reason why it was removed from jQuery 1.9.

Consider using toggleClass instead, which is fully supported by jQuery:

 function a(){...} function b(){...} 

Say, for example, that the trigger is an onclick event, therefore:

First option:

 $('#test').on('click', function (event) { $(this).toggleClass('toggled'); if ($(this).hasClass('toggled')) { a(); } else{ b(); } } 

You can also send handler functions as parameters:

Second option:

 $('#test').on('click',{handler1: a, handler2: b}, function (event) { $(this).toggleClass('toggled'); if ($(this).hasClass('toggled')) { event.data.handler1(); } else{ event.data.handler2(); } } 
+4
Sep 04 '15 at
source share

Use multiple functions and boolean. Here's the template, not the full code:

  var state = false, oddONes = function () {...}, evenOnes = function() {...}; $("#time").click(function(){ if(!state){ evenOnes(); } else { oddOnes(); } state = !state; }); 

or

  var cases[] = { function evenOnes(){...}, // these could even be anonymous functions function oddOnes(){...} // function(){...} }; var idx = 0; // should always be 0 or 1 $("#time").click(function(idx){cases[idx = ((idx+1)%2)]()}); // corrected 

(Note that the second one is turned off from my point of view, and I mix languages ​​a lot, so the exact syntax is not guaranteed. It should be close to real Javascript through.)

+1
Feb 06 2018-11-11T00:
source share

If everything you do supports boolean isEven , then you can check if the isEven class isEven in the element, and then switch that class.

Using a common variable such as count is bad practice. Ask yourself, what is the scope of this variable, think about it, if you had 10 elements that you want to switch on your page, would you create 10 variables or an array or variables to store your state? Probably not.

Edit:
jQuery has a switchClass method that , in combination with hasClass, can be used to animate between two widths you specify. This is beneficial because you can change these sizes later in your stylesheet or add other options, such as background-color or margin, for the transition.

+1
Feb 06 2018-11-11T00:
source share

changing the first answer, you can switch between n functions:

 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus.com®"> <!-- <script src="../js/jquery.js"></script> --> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <title>my stupid example</title> </head> <body> <nav> <div>b<sub>1</sub></div> <div>b<sub>2</sub></div> <div>b<sub>3</sub></div> <!-- .......... --> <div>b<sub>n</sub></div> </nav> <script type="text/javascript"> <!-- $(document).ready(function() { (function($) { $.fn.clickToggle = function() { var ta=arguments; this.data('toggleclicked', 0); this.click(function() { id= $(this).index();console.log( id ); var data = $(this).data(); var tc = data.toggleclicked; $.proxy(ta[id], this)(); data.toggleclicked = id }); return this; }; }(jQuery)); $('nav div').clickToggle( function() {alert('First handler');}, function() {alert('Second handler');}, function() {alert('Third handler');} //...........how manny parameters you want..... ,function() {alert('the 'n handler');} ); }); //--> </script> </body> </html> 
+1
Jan 06 '18 at 12:46
source share



All Articles