├── tests
├── index.html
└── tests.js
├── README.md
└── jquery.func_toggle.js
/tests/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | jQuery Function Toggle Plugin
2 | ===
3 | Copyright (c) 2011 Felix Kling. Dual licensed under the MIT or GPL Version 2 licenses.
4 |
5 |
6 | Overview
7 | ---
8 |
9 | This plugin enables you to bind multiple event handlers that should be executed one after another.
10 |
11 | **Features:**
12 |
13 | - Provides the same interface and features as `bind()`
14 | - Non-function arguments, apart from `false`, are handled as empty functions
15 |
16 | Usage
17 | ---
18 |
19 | The function `funcToggle` provides the same interface as `bind` but accepts multiple event handlers:
20 |
21 | funcToggle(eventType, [eventData], handler(eventObject), [handler(eventObject), ...])
22 |
23 |
24 |
25 | Examples:
26 | ---
27 |
28 | This changes the text color on each consecutive click, from to original color to red, to green, to black, to red again and so forth:
29 |
30 | element.funcToggle('click', function() {
31 | $(this).css('color', 'red');
32 | }, function() {
33 | $(this).css('color', 'green');
34 | }, function() {
35 | $(this).css('color', 'black');
36 | });
37 |
38 |
39 | Bind handlers for multiple events:
40 |
41 | element.funcToggle({
42 | 'click': [function() {
43 | $(this).css('color', 'red');
44 | }, function() {
45 | $(this).css('color', 'green');
46 | }, function() {
47 | $(this).css('color', 'black');
48 | }],
49 | 'mouseover': [function() {
50 | $(this).css('background-color', 'red');
51 | }, function() {
52 | $(this).css('background-color', 'white');
53 | }]
54 | });
55 |
--------------------------------------------------------------------------------
/jquery.func_toggle.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Function Toggle Pluing
3 | * Copyright 2011, Felix Kling
4 | * Dual licensed under the MIT or GPL Version 2 licenses.
5 | */
6 |
7 | ;(function (factory) {
8 | if (typeof define === 'function' && define.amd) {
9 | // AMD. Register as an anonymous module.
10 | define(['jquery'], factory);
11 | } else {
12 | // Browser globals
13 | factory(jQuery);
14 | }
15 | }) (function($) {
16 | $.fn.funcToggle = function(type, data) {
17 | var dname = "jqp_eventtoggle_" + type + (new Date()).getTime(),
18 | funcs = Array.prototype.slice.call(arguments, 2),
19 | numFuncs = funcs.length,
20 | empty = function() {},
21 | false_handler = function() {return false;};
22 |
23 | if(typeof type === "object") {
24 | for( var key in type) {
25 | $.fn.funcToggle.apply(this, [key].concat(type[key]));
26 | }
27 | return this;
28 | }
29 | if($.isFunction(data) || data === false) {
30 | funcs = [data].concat(funcs);
31 | numFuncs += 1;
32 | data = undefined;
33 | }
34 |
35 | funcs = $.map(funcs, function(func) {
36 | if(func === false) {
37 | return false_handler;
38 | }
39 | if(!$.isFunction(func)) {
40 | return empty;
41 | }
42 | return func;
43 | });
44 |
45 | this.data(dname, 0);
46 | this.bind(type, data, function(event) {
47 | var data = $(this).data(),
48 | index = data[dname];
49 | funcs[index].call(this, event);
50 | data[dname] = (index + 1) % numFuncs;
51 | });
52 | return this;
53 | };
54 | });
55 |
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | test('funcToggle() without data', function() {
3 | expect(2);
4 | $(document.body).funcToggle('click', function() {
5 | ok(true, "First handler called");
6 | },
7 | function() {
8 | ok(true, "Second handler called");
9 | }).click().click().unbind('click');
10 | });
11 |
12 | test('funcToggle() functions are called in right order', function() {
13 | var counter = 0;
14 | $(document.body).funcToggle('click', function() {
15 | equals(counter, 0, "First handler called");
16 | counter++;
17 | },
18 | function() {
19 | equals(counter, 1, "Second handler called");
20 | }).click().click().unbind('click');
21 | });
22 |
23 | test('funcToggle() first function is called again', function() {
24 | var counter = 0;
25 | var lastCalled = false;
26 | $(document.body).funcToggle('click', function() {
27 | if(!lastCalled) {
28 | equals(counter, 0, "First handler called");
29 | }
30 | else {
31 | equals(counter, 2, "First handler called again");
32 | }
33 | counter++;
34 |
35 | },
36 | function() {
37 | equals(counter, 1, "Second handler called");
38 | lastCalled = true;
39 | counter++;
40 | }).click().click().click().unbind('click');
41 | });
42 |
43 | test('funcToggle() this is correctly set', function() {
44 | $(document.body).funcToggle('click', {foo: 'bar'}, function() {
45 | equals(this, document.body, "First handler: this is correctly set");
46 | },
47 | function(event) {
48 | equals(this, document.body, "Second handler: this is correctly set");
49 | }).click().click().unbind('click');
50 | });
51 |
52 |
53 | test('funcToggle() with data', function() {
54 | $(document.body).funcToggle('click', {foo: 'bar'}, function(event) {
55 | ok(event.data, "First handler: event data set");
56 | equals(event.data.foo, 'bar', "First handler: event data correctly set");
57 | },
58 | function(event) {
59 | ok(event.data, "Second handler: event data set");
60 | equals(event.data.foo, 'bar', "Second handler: event data correctly set");
61 | }).click().click().unbind('click');
62 | });
63 |
64 |
65 |
66 | test('funcToggle() with a lot of event handlers', function() {
67 | var num = 20,
68 | counter = 0,
69 | lastCalled = false,
70 | funcs = [];
71 |
72 | expect(num+1);
73 |
74 | for(var i = 0; i < num; i++) {
75 | funcs.push((function(index) {
76 | var func;
77 | if(index === 0) {
78 | func = function() {
79 | if(!lastCalled) {
80 | equals(counter, index, "First function called");
81 | }
82 | else {
83 | equals(counter, num, "First function called again");
84 | }
85 | counter++;
86 | };
87 | }
88 | else if(index === (num - 1)) {
89 | func = function() {
90 | equals(counter, index, "Last function called");
91 | lastCalled = true;
92 | counter++;
93 | }
94 | }
95 | else {
96 | func = function() {
97 | equals(counter, index, (index+1) + ". function called");
98 | counter++;
99 | }
100 | }
101 | return func;
102 | }(i)));
103 | }
104 |
105 | $(document.body).funcToggle.apply($(document.body), ['click'].concat(funcs));
106 | for(var i = 0; i <= num; i++) {
107 | $(document.body).click();
108 | }
109 | $(document.body).unbind('click');
110 | });
111 | });
112 |
--------------------------------------------------------------------------------