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

IT技术 javascript jquery
2021-01-28 04:21:03

我正在寻找一种方法,可以在单击某物时运行两个单独的操作/功能/“代码块”,然后在再次单击同一事物时运行完全不同的块。我把这个放在一起。我想知道是否有更有效/优雅的方式。我知道 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);
    }
});
6个回答

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

注意:似乎至少从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:

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

@jlcd:这就是为什么我把它放在答案的开头。我编辑了我的答案以更加强调它,您认为现在更好了吗?TBH,我写了代码,后来发现了另.toggle一种方法。虽然我不想扔掉那个代码......
2021-03-11 04:21:03
@Syed:当然,只需将data.toggleclicked元素设置为要重置的索引即可。
2021-03-12 04:21:03
我不明白……为什么不直接使用api.jquery.com/toggle-event你甚至在你的回答中提到了它......也许你应该突出显示那部分,因为它是一个原生的 jQuery 方法。
2021-03-15 04:21:03
2021-03-18 04:21:03
@ThomasReggi:谢谢,更新。我写这个的时候已经很晚了;) 但是,没有必要使用this.each,特别是因为这将为funcs每个元素创建一个数组和新的事件处理函数。修复了它并添加了演示。
2021-04-09 04:21:03

演示

.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);
@urjitonrails 很高兴它有帮助:)
2021-03-11 04:21:03
如此巧妙的解决方案。队友的欢呼声!
2021-03-20 04:21:03
这是完美的,直到今天!
2021-03-23 04:21:03
惊人的解决方案!!!从来不知道这个.one()方法,但它非常有用。谢谢
2021-03-29 04:21:03

微型 jQuery 插件

如果你想要你自己的可链接的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>


简单功能切换器

现场演示

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

就这样。
诀窍是为thisObject设置一个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);
}); 

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

$("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

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

您只需将a,b函数存储在一个数组中,onclick您只需颠倒数组顺序并执行该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 演示
JavaScript 演示

创建一个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 );
@koz.tog只是我们添加到this对象的一个属性就像你说Person.name = "koz"Person 是一个对象一样,你分配一个name属性而不是一个值。有关 XOR 运算符的更多信息,请^访问:stackoverflow.com/a/22061240/383904(您可以在我的回答中找到相同的链接;))
2021-03-13 04:21:03
我明白了大部分。但我不明白“tog”是从哪里来的?el.tog^=1 如何在 0 和 1 之间交替切换?非常感谢
2021-03-26 04:21:03
很棒的答案!谢谢
2021-04-09 04:21:03
@RokoC.Buljan 感谢回复,非常感谢。我查看了链接,但它没有解释我喜欢理解的数学原理。我知道它返回 0, 1, 0, 1 ...但它是如何做到的??。“^=1”在数学中实际上意味着什么,或者等于 0,1,0,1。谢谢
2021-04-09 04:21:03
@koz 想想二进制、零和一。XOR 运算符在每个位位置返回 a one,其中一个但不是两个操作数的相应位都是ones现在,正如您所注意到的,我们总是反对ones( 1)运算符:operand^1所以这里有一个结果表:0^1 =11^1 =0到目前为止一切顺利 - 结果正在改变!但是为了实际修改我们的运算符,el.tog您需要使用赋值运算符 ( =) - 就这样!el.tog^=1. 现在回顾一下小表格,您将了解现在分配给el.tog属性的值。
2021-04-10 04:21:03

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

var oddClick = true;
$("#time").click(function() {
    $(this).animate({
        width: oddClick ? 260 : 30
    },1500);
    oddClick = !oddClick;
});
这仅适用于唯一元素。我建议删除oddClick-part 并将width:-line替换为width: $(this).width() == 30 ? 260 : 30.
2021-03-28 04:21:03

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

var x = false;
$(element).on('click', function(){
 if (!x){
  //function
  x = true;
 }
 else {
  //function
  x = false;
 }
});
谢谢:) 非常有用!
2021-03-11 04:21:03