Alternativa ao método .toggle () do jQuery que suporta eventData?

A documentação do jQuery para o método .toggle() diz:

O método .toggle () é fornecido por conveniência. É relativamente simples implementar o mesmo comportamento manualmente, e isso pode ser necessário se as suposições incorporadas em .toggle () forem limitantes.

As suposições incorporadas no .toggle provaram ser limitantes para minha tarefa atual, mas a documentação não elabora como implementar o mesmo comportamento. Eu preciso passar eventData para as funções de manipulador fornecidas toggle() , mas parece que apenas .bind() suportará isso, não .toggle() .

Minha primeira inclinação é usar um sinalizador global para uma única function de manipulador para armazenar o estado de clique. Em outras palavras, ao invés de:

 $('a').toggle(function() { alert('odd number of clicks'); }, function() { alert('even number of clicks'); }); 

faça isso:

 var clicks = true; $('a').click(function() { if (clicks) { alert('odd number of clicks'); clicks = false; } else { alert('even number of clicks'); clicks = true; } }); 

Eu não testei o último, mas suspeito que funcionaria. Essa é a melhor maneira de fazer algo assim, ou há uma maneira melhor de que estou perdendo?

Obrigado!

Parece uma maneira razoável de fazer isso … Eu apenas sugeriria que você fizesse uso dos utilitários de armazenamento de dados do jQuery ao invés de introduzir uma variável extra (o que poderia se tornar uma dor de cabeça se você quisesse acompanhar um monte de links) . Então, com base no seu exemplo:

 $('a').click(function() { var clicks = $(this).data('clicks'); if (clicks) { alert('odd number of clicks'); } else { alert('even number of clicks'); } $(this).data("clicks", !clicks); }); 

Aqui está um plugin que implementa uma alternativa ao .toggle() , especialmente desde que foi removido no jQuery 1.9+.

Como usar:

A assinatura deste método é:

 .cycle( functions [, callback] [, eventType]) 
  • functions [Array]: Uma matriz de funções para alternar entre
  • callback [Função]: Uma function que será executada na conclusão de cada iteração. Será passado a iteração atual e a saída da function atual. Pode ser usado para fazer algo com o valor de retorno de cada function no array de functions .
  • eventType [String]: Uma string especificando os tipos de events a serem eventType , por exemplo. "click mouseover"

Um exemplo de uso é:

 $('a').cycle([ function() { alert('odd number of clicks'); }, function() { alert('even number of clicks'); } ]); 

Eu incluí uma demonstração aqui .

Código de Plugin:

 (function ($) { if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(accumulator) { if (this === null || this === undefined) throw new TypeError("Object is null or undefined"); var i = 0, l = this.length >> 0, curr; if (typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception." throw new TypeError("First argument is not callable"); if (arguments.length < 2) { if (l === 0) throw new TypeError("Array length is 0 and no second argument"); curr = this[0]; i = 1; // start accumulating at the second element } else curr = arguments[1]; while (i < l) { if (i in this) curr = accumulator.call(undefined, curr, this[i], i, this); ++i; } return curr; }; } $.fn.cycle = function () { var args = Array.prototype.slice.call(arguments).reduce(function (p, c, i, a) { if (i == 0) { p.functions = c; } else if (typeof c == "function") { p.callback = c; } else if (typeof c == "string") { p.events = c; } return p; }, {}); args.events = args.events || "click"; console.log(args); if (args.functions) { var currIndex = 0; function toggler(e) { e.preventDefault(); var evaluation = args.functions[(currIndex++) % args.functions.length].apply(this); if (args.callback) { callback(currIndex, evaluation); } return evaluation; } return this.on(args.events, toggler); } else { //throw "Improper arguments to method \"alternate\"; no array provided"; } }; })(jQuery);