Javascript jQuery 单击/在两个函数之间切换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4911577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:44:04  来源:igfitidea点击:

jQuery click / toggle between two functions

javascriptjquery

提问by ThomasReggi

I am looking for a way to have two separate operations / functions / "blocks of code" run when something is clicked and then a totally different block when the same thing is clicked again. I put this together. I was wondering if there was a more efficient / elegant way. I know about jQuery .toggle()but it kind of sucks.

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

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

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

采纳答案by Felix Kling

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

jQuery 有两个方法称为.toggle(). 在另一个[文件]不正是你想要的click事件。

Note:It seems that at least since jQuery 1.7, this version of .toggleis deprecated, probably for exactly that reason, namely that two versions exist. Using .toggleto change the visibility of elements is just a more common usage. The method was removed in jQuery 1.9.

注意:似乎至少从jQuery 1.7 开始,这个版本已.toggle弃用,可能正是出于这个原因,即存在两个版本。利用.toggle改变元素的知名度仅仅是一个更常见的用法。该方法已在 jQuery 1.9删除

Below is an example of how one could implement the same functionality as a plugin (but probably exposes 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 don't say this is the best implementation! I bet it can be improved in terms of performance)

(免责声明:我不是说这是最好的实现!我打赌它可以在性能方面得到改进)

And then call it with:

然后调用它:

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

Update 2:

更新 2:

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

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

回答by Tushar Gupta - curioustushar

DEMO

演示

.one()documentation.

.one()文档。

I am very late to answer but i think it's shortest code and might 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's 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);

回答by Roko C. Buljan

Micro jQuery Plugin

微型 jQuery 插件

If you want your own chainable clickTogglejQuery Method you can do it like:

如果你想要你自己的可链接的clickTogglejQuery 方法,你可以这样做:

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 Functions Toggler

简单功能切换器

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 even shorter (why would one, right?!) you can use the Bitwise XOR*Docsoperator like:
DEMO

如果您希望它更短(为什么会这样,对吧?!)您可以使用Bitwise XOR *Docs运算符,例如:
DEMO

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

That's all.
The trick is to set to the thisObject a booleanproperty tog, and toggle it using negation(tog = !tog)
and put the needed function calls in a Conditional Operator?:



就这样。
诀窍是为thisObject设置一个boolean属性tog,并使用否定( tog = !tog)切换它
并将所需的函数调用放入条件运算符中?:





In OP's example (even with multiple elements) could look like:

在 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:You can also store-togglelike:
DEMO:

另外您还可以存储-toggle,例如:
DEMO

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

but it was not the OP's exact request for he's looking for a way to have two separate operations / functions

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



Using Array.prototype.reverse:

使用Array.prototype.reverse

Note: this will not store the current Toggle state but just inverse our functions positions in Array (It has it's uses...)

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

You simply store your a,bfunctions inside an array, onclickyou simply reverse the array order and execute the array[1]function:

您只需将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"...
});


SOME MASHUP!

一些混搭!

jQuery DEMO
JavaScript DEMO

jQuery 演示
JavaScript 演示

Create a nice function toggleAB()that will contain your two functions, put them in Array, and at the end of the array you simply execute the function [0 // 1] respectively depending on the togproperty that's passed to the function from the thisreference:

创建一个toggleAB()包含两个函数的好函数,将它们放入 Array,然后在数组的末尾,您只需0 // 1根据togthis引用传递给函数的属性分别执行函数 [ ] :

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

回答by dom

I would do something like this for the code you showed, if all you need to do is toggle a value :

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

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

回答by metamlkshk

I used this to create a toggle effect between two functions.

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

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

回答by Dudi

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

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

Consider using toggleClass instead that is fully supported by jQuery:

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

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

Let's say for example that your event trigger is onclick, so:

例如,假设您的事件触发器是 onclick,因此:

First option:

第一个选项:

$('#test').on('click', function (event) {

    $(this).toggleClass('toggled');

    if ($(this).hasClass('toggled')) {
        a();
    } else{
        b();
    }
}

You can also send the 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();
    }
}

回答by nedk

If all you're doing is keeping a boolean isEventhen you can consider checking if a class isEvenis on the element then toggling that class.

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

Using a shared variable like count is kind of bad practice. Ask yourself what is the scope of that variable, think of if you had 10 items that you'd want to toggle on your page, would you create 10 variables, or an array or variables to store their state? Probably not.

使用像 count 这样的共享变量是一种不好的做法。问问自己这个变量的作用域是什么,想想如果你有 10 个要在页面上切换的项目,你会创建 10 个变量,还是创建一个或多个变量来存储它们的状态?可能不是。

Edit:
jQuery has a switchClassmethod that, when combined with hasClass can be used to animate between the two width you have defined. This is favourable because you can change these sizes later in your stylesheet or add other parameters, like background-color or margin, to transition.

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

回答by Charlie Martin

Use a couple of functions and a boolean. Here's a pattern, not 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 the second is off the top of my head and I mix languages a lot, so the exact syntax isn't guaranteed. Should be close to real Javascript through.)

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

回答by Constantin

modifying the first answer you are able to switch between n functions :

修改第一个答案,您可以在 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>

回答by ashkan nasirzadeh

one line solution:basic idea:

一行解决方案:基本思路:

$('sth').click(function () {
    let COND = $(this).propery == 'cond1' ? 'cond2' : 'cond1';
    doSomeThing(COND);
})

examples on jsfiddle

jsfiddle上的例子

example 1, changing innerHTML of an element in a toggle-mode:

示例 1,在切换模式下更改元素的 innerHTML:

$('#clickTest1').click(function () {
    $(this).html($(this).html() == 'click Me' ? 'clicked' : 'click Me');
});

example 2, toggling displays between "none" and "inline-block":

示例 2,在“none”和“inline-block”之间切换显示:

$('#clickTest2, #clickTest2 > span').click(function () {
    $(this).children().css('display', $(this).children().css('display') == 'inline-block' ? 'none' : 'inline-block');
});