81896

Alternative to jQuery's .toggle() method that supports eventData?

Question:

The <a href="http://api.jquery.com/toggle/" rel="nofollow">jQuery documentation</a> for the .toggle() method states:

<blockquote>

The .toggle() method is provided for convenience. It is relatively straightforward to implement the same behavior by hand, and this can be necessary if the assumptions built into .toggle() prove limiting.

</blockquote>

The assumptions built into .toggle have proven limiting for my current task, but the documentation doesn't elaborate on how to implement the same behavior. I need to pass eventData to the handler functions provided to toggle(), but it appears that only .bind() will support this, not .toggle().

My first inclination is to use a flag that's global to a single handler function to store the click state. In other words, rather than:

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

do this:

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

I haven't tested the latter, but I suspect it would work. Is this the best way to do something like this, or is there a better way that I'm missing?

Thanks!

Answer1:

Seems like a reasonable way to do it... I'd just suggest that you make use of jQuery's <a href="http://api.jquery.com/category/miscellaneous/data-storage/" rel="nofollow">data storage</a> utilities rather than introducing an extra variable (which could become a headache if you wanted to keep track of a whole bunch of links). So based of your example:

$('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); });

Answer2:

Here is a plugin that implements an alternative to .toggle(), especially since it has been removed in jQuery 1.9+.

<strong>How to use:</strong>

The signature for this method is:

.cycle( functions [, callback] [, eventType]) <ul><li>functions [Array]: An array of functions to cycle between</li> <li>callback [Function]: A function that will be executed on completion of each iteration. It will be passed the current iteration and the output of the current function. Can be used to do something with the return value of each function in the functions array.</li> <li>eventType [String]: A string specifying the event types to cycle on, eg. "click mouseover"</li> </ul>

An example of usage is:

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

I've included a demonstration <a href="http://jsfiddle.net/SRV4y/" rel="nofollow">here</a>.

<strong>Plugin code:</strong>

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

Recommend

  • How does sizeof work for int types?
  • clflush to invalidate cache line via C function
  • HttpClient with WebView
  • How do I force a browser window to always be on top and in focus
  • Refresh other frame, from another frame. Jquery
  • Full 8 bit adder, illogical output
  • help('modules') crashing? Not sure how to fix
  • Can XOR be expressed using SKI combinators?
  • C#: Import/Export Settings into/from a File
  • Which open source license has no forking [closed]
  • How Get arguments value using inline assembly in C without Glibc?
  • How can I replace the server in Web Component Tester
  • How to make R's read_csv2() recognise the text characters properly
  • C# program and C++ DLL compiled for 32-bit system crash on 64-bit system
  • Implementation of State Monad
  • How integrated is Collada to OpenGL ES
  • Ionic 2 storage is not cleaning up on uninstall - Only for signed APK
  • How do I pass the string value parameter of the selected list item from an auto-populated dropdown l
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Comma separated Values
  • PHP: When would you need the self:: keyword?
  • How to delete a row from a dynamic generate table using jquery?
  • using HTMLImports.whenReady not working in chrome
  • Why joiner is not used after Sequence generator or Update statergy
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • How to stop GridView from loading again when I press back button?
  • File not found error Google Drive API
  • Authorize attributes not working in MVC 4
  • Bitwise OR returns boolean when one of operands is nil
  • Is it possible to post an object from jquery to bottle.py?
  • EntityFramework adding new object to nested object collection
  • sending mail using smtp is too slow
  • Does armcc optimizes non-volatile variables with -O0?
  • Busy indicator not showing up in wpf window [duplicate]
  • costura.fody for a dll that references another dll
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • How can I use `wmic` in a Windows PE script?
  • How to load view controller without button in storyboard?