jQuery点击/切换两个函数

我正在寻找一种方法来有两个单独的操作/功能/“块代码”运行时,点击一个,然后一个完全不同的块,当同样的事情再次点击。 我把这个放在一起。 我想知道是否有一个更高效/优雅的方式。 我知道jQuery .toggle(),但它有点糟糕。

在这里工作: 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); } }); 

jQuery有两个叫做.toggle()方法。 另一个[文档]完全是你想要的点击事件。

注意:至少从jQuery 1.7开始 ,这个版本的.toggle已经被废弃了 ,可能正是出于这个原因,也就是说存在两个版本。 使用.toggle来改变元素的可见性只是一个更常见的用法。 该方法在jQuery 1.9中删除

下面是一个如何实现与插件相同的功能的例子(但可能会暴露与内置版本相同的问题(请参阅文档中的最后一段))。


 (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

(免责声明:我不认为这是最好的实现!我敢打赌,它可以提高性能)

然后用以下方式调用它:

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

更新2:

同时,我为此创建了一个适当的插件。 它接受任意数量的函数,可以用于任何事件。 它可以在GitHub上找到 。

DEMO

.one()文档。

我很晚回答,但我认为这是最短的代码,可能会有所帮助。

 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); 

用Op的代码演示

 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); 

微型jQuery插件

如果你想要自己的连锁clickToggle的 jQuery方法,你可以这样做:

DEMO

 jQuery.fn.clickToggle = function(a,b) { function cb(){ [b,a][this._tog^=1].call(this); } return this.on("click", cb); }; 

 $("selector").clickToggle(function() { // Do something here }, function() { // Do thething here }); // (you can chain here other jQuery methods) 

简单函数Toggler

现场演示

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

如果你希望它更短( 为什么会一个,对吗?! ),你可以使用Bitwise XOR * Docs运算符,如:
DEMO

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

就这样。
诀窍是设置this对象的boolean属性tog ,并使用否定tog = !tog
并将所需的函数调用放在条件运算符中 ?:


在OP的例子中(即使有多个元素)可能看起来像:

 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); }); 

另外你也可以存储像这样的:
演示

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

但这不是OP的确切要求,他looking for a way to have two separate operations / functions


使用Array.prototype.reverse :

注意 :这不会存储当前的切换状态,而只是在Array中反转我们的函数位置(它有用…)

您只需将您的a,b函数存储在一个数组中,然后单击您的数组顺序,然后执行array[1]函数:

现场演示

 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"... }); 

一些混搭!

jQuery DEMO
JavaScript演示

创建一个很好的函数toggleAB() ,它将包含你的两个函数, 把它们放在数组中在数组的末尾你可以简单地执行函数[ 0 // 1 ],这取决于传递给函数的tog属性this参考:

 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 ); 

我会为你显示的代码做这样的事情,如果你需要做的只是切换一个值:

 var oddClick = true; $("#time").click(function() { $(this).animate({ width: oddClick ? 260 : 30 },1500); oddClick = !oddClick; }); 

我用这个来创建两个函数之间的切换效果。

 var x = false; $(element).on('click', function(){ if (!x){ //function x = true; } else { //function x = false; } }); 

我不认为你应该实现切换方法,因为它是从jQuery 1.9中删除的原因。

考虑使用完全由jQuery支持的toggleClass:

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

比方说,你的事件触发器是onclick,所以:

第一个选项:

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

您也可以将处理函数作为参数发送:

第二个选项:

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

如果你所做的只是保持一个布尔值isEven那么你可以考虑检查一个类是否在该元素上,然后切换该类。

使用像count这样的共享变量是一种糟糕的做法。 问问你自己,这个变量的范围是什么,想想如果你有10个项目,你想在你的页面上切换,你会创建10个变量,或者一个数组或变量来存储他们的状态? 可能不会。

编辑:
jQuery有一个switchClass方法,与hasClass结合使用可以在你定义的两个宽度之间进行动画处理。 这是有利的,因为您可以稍后在样式表中更改这些大小,或添加其他参数(如背景颜色或边距)以进行过渡。

使用几个函数和一个布尔值。 这是一个模式,而不是完整的代码:

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

要么

  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 

(请注意,第二个是我的头顶,我混合了很多语言,所以确切的语法不能保证,应该靠近真正的Javascript。)