admin管理员组文章数量:1340773
I have a function that I want it execute alternating processes every time it's triggered. Any help on how I would achieve this would be great.
function onoff(){
statusOn process /*or if on*/ statusOff process
}
I have a function that I want it execute alternating processes every time it's triggered. Any help on how I would achieve this would be great.
function onoff(){
statusOn process /*or if on*/ statusOff process
}
Share
Improve this question
edited Jun 6, 2011 at 12:39
Domenic
113k42 gold badges226 silver badges273 bronze badges
asked Jun 2, 2011 at 20:46
fancyfancy
51.5k64 gold badges158 silver badges230 bronze badges
1
- It's fascinating to see how many different ways we can solve the same problem. Great question! – Jonathan Beebe Commented Jun 2, 2011 at 22:13
7 Answers
Reset to default 7One interesting aspect of JavaScript is that functions are first-class objects, meaning they can have custom properties:
function onoff() {
onoff.enabled = !onoff.enabled;
if(onoff.enabled) {
alert('on');
} else {
alert('off');
}
}
For this to work, your function should have a name. If your function is anonymous (unnamed), you can try to use arguments.callee
to access it, but that is deprecated in the new ES5 standard and not possible when using its strict mode.
With the use of closures, you can define a static variable that is only accessible by the function itself:
var toggle = (function()
{
var state = true;
return function()
{
if(state)
alert("A");
else
alert("B");
state = !state;
};
})();
Now you can repeatedly invoke toggle()
, and it would alternate between "A"
and "B"
. The state
variable is unaccessible from the outside, so you don't pollute the global variable scope.
Use closures. In addition to closures, this method demonstrates arbitrary arguments and arbitrary numbers of functions to cycle through:
Function cycler
function cycle() {
var toCall = arguments;
var which = 0;
return function() {
var R = toCall[which].apply(this, arguments);
which = (which+1) % toCall.length; // see NOTE
return R;
}
}
Demo:
function sum(a,b) {return a+b}
function prod(a,b) {return a*b}
function pow(a,b) {return Math.pow(a,b)}
function negate(x) {return -x;}
var f = cycle(sum, prod, pow, negate);
console.log(f(2,10)); // 12
console.log(f(2,10)); // 20
console.log(f(2,10)); // 1024
console.log(f(2)); // -2
// repeat!
console.log(f(2,10)); // 12
console.log(f(2,10)); // 20
console.log(f(2,10)); // 1024
console.log(f(2)); // -2
Arbitrary cycler
Alternatively if you do not wish to assume all cycled things are functions, you can use this pattern. In some ways it is more elegant; in some ways it is less elegant.
function cycle() {
var list = arguments;
var which = 0;
return function() {
var R = list[which];
which = (which+1) % toCall.length; // see NOTE
return R;
}
}
Demo:
var cycler = cycle(function(x){return x}, 4, function(a,b){return a+b});
cycler()(1); // 1
cycler(); // 4
cycler()(1,5); // 6
// repeat!
cycler()(1); // 1
cycler(); // 4
cycler()(1,5); // 6
NOTE: Because javascript thinks 10000000000000001%2
is 0 (i.e. that this number is even), this function must be three codelines longer than necessary, or else you will only be able to call this function 10 quadrillion times before it gives an incorrect answer. You are unlikely to reach this limit in a single browsing session... but who knows
If I'm understanding what you want, this may be what you're looking for:
var AlternateFunctions = function() {
var one = function() {
// do stuff...
current = two;
}, two = function() {
// do stuff...
current = one;
}, current = one;
return function() {
current();
}
}();
Then calling AlternateFunctions();
will cycle between one()
and two()
There are a couple of good answers already posted, but I'm wondering what you're trying to achieve. If you're keeping track of some DOM element's state, instead of having state saved within the function, you should check the state of the element so that the function isn't operating in a vacuum (and possibly not doing what you expect). You can check some attribute, e.g., class:
function onoff(obj){
if(obj.className === 'on') {
obj.className = 'off';
}else{
obj.className = 'on';
}
}
var last=0;
function toggle() {
if(last) {
last=0;
// do process 2
}
else {
last=1;
// do process 1
}
}
See jsfiddle demo
var status=true;
function onOff(el){
/*
* toggle
*/
status = (status ? false : true);
status
? el.html('on')
: el.html('off');
}
版权声明:本文标题:javascript - What is the best way to have a function toggle between two different processes? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743651571a2516416.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论