我正在寻找一种方法,在点击某些内容时运行两个单独的操作/函数/“代码块”,然后在再次单击相同的内容时运行完全不同的块。我把它放在一起。我想知道是否有更有效/更优雅的方式。我知道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);
}
});
答案 0 :(得分:67)
jQuery有两个名为.toggle()
的方法。 other one [docs]完全符合您对点击事件的要求。
注意:似乎至少从 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));
(免责声明:我不是说这是最好的实现!我敢打赌它可以在性能方面得到改善)
然后用:
来调用它$('#test').clickToggle(function() {
$(this).animate({
width: "260px"
}, 1500);
},
function() {
$(this).animate({
width: "30px"
}, 1500);
});
更新2:
与此同时,我为此创建了一个合适的插件。它接受任意数量的函数,可用于任何事件。 It can be found on GitHub
答案 1 :(得分:58)
.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);
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);
答案 2 :(得分:47)
如果您想要自己的可链接 clickToggle jQuery方法,可以这样做:
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>
<强> LIVE DEMO 强>
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
对象a boolean
属性tog
,并使用否定(tog = !tog
)
并把所需的函数调用
在 Conditional Operator ?:
中
在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);
});
ALSO :您还可以 存储 -toggle ,如: DEMO:
$("selector").click(function() {
$(this).animate({width: (this.tog ^= 1) ? 260 : 30 });
});
但这不是OP的确切要求 looking for a way to have two separate operations / functions
注意:这不会存储当前的Toggle状态,只是反转我们在Array中的函数位置(它有它的用途......)
您只需将 a,b 函数存储在数组中, onclick 只需反转数组顺序并执行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"...
});
<强> jQuery DEMO 强>
的 JavaScript DEMO 强>
创建一个包含两个函数的好函数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 );
答案 3 :(得分:24)
如果你需要做的就是切换一个值,我会为你展示的代码执行类似的操作:
var oddClick = true;
$("#time").click(function() {
$(this).animate({
width: oddClick ? 260 : 30
},1500);
oddClick = !oddClick;
});
答案 4 :(得分:14)
我用它来创建两个函数之间的切换效果。
var x = false;
$(element).on('click', function(){
if (!x){
//function
x = true;
}
else {
//function
x = false;
}
});
答案 5 :(得分:4)
我认为你不应该实现toggle方法,因为有理由将它从jQuery 1.9中删除。
考虑使用toggleClass而不是jQuery完全支持:
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();
}
}
答案 6 :(得分:1)
使用几个函数和一个布尔值。这是一个模式,而不是完整的代码:
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通过。)
答案 7 :(得分:1)
如果您所做的只是保留布尔值isEven
,那么您可以考虑检查元素isEven
是否在元素上,然后切换该类。
使用像count这样的共享变量是一种不好的做法。问问自己该变量的范围是什么,想想你是否有10个要在页面上切换的项目,你会创建10个变量,还是一个数组或变量来存储它们的状态?可能不是。
编辑:
jQuery有一个switchClass方法,当与hasClass结合使用时,可用于在你定义的两个宽度之间进行动画处理。这是有利的,因为您可以稍后在样式表中更改这些尺寸,或者添加其他参数(如背景颜色或边距)以进行转换。
答案 8 :(得分:0)
修改第一个答案,你可以在n个函数之间切换:
<!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>
答案 9 :(得分:0)
一种解决方案: 基本思路:
$('sth').click(function () {
let COND = $(this).propery == 'cond1' ? 'cond2' : 'cond1';
doSomeThing(COND);
})
示例1,以切换模式更改元素的innerHTML:
$('#clickTest1').click(function () {
$(this).html($(this).html() == 'click Me' ? 'clicked' : 'click Me');
});
示例2,在“ none”和“ inline-block”之间切换显示:
$('#clickTest2, #clickTest2 > span').click(function () {
$(this).children().css('display', $(this).children().css('display') == 'inline-block' ? 'none' : 'inline-block');
});