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