1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/*!
* @file jQuery Once
* @description Act on jQuery elements only once.
* @version 2.0.0-alpha.5
* @link http://github.com/robloach/jquery-once
* @author Rob Loach (http://robloach.net)
* @license MIT, GPL-2.0
*/
(function (factory) {
"use strict";
if (typeof exports === 'object') {
factory(require('jquery'));
} else if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(jQuery);
}
}(function ($) {
"use strict";
var cache = {}, uuid = 0;
/**
* Filters elements by whether they have not yet been processed.
*
* @param {(string|function)} [id]
* (Optional) If this is a string, then it will be the data ID used
* to determine whether it has already been processed or not.
*
* If the id parameter is a function, it will be passed off to the fn
* parameter and the id will become a unique identifier, represented as a
* number.
*
* When the id is neither a string or a function, it becomes a unique
* identifier, depicted as a number. The element's data ID will then be
* represented in the form of "jquery-once-#".
* @param {function} [fn]
* (Optional) If given, this function will be called for each element that
* has not yet been processed. The function's return value follows the same
* logic as $.each(). Returning true will continue to the next matched
* element in the set, while returning false will entirely break the
* iteration.
* @returns jQuery element collection of elements that have now run once.
*
* @example
* // Change the color to green only once.
* $('p').once('changecolor', function() {
* // This function is called for every p element that hasn't been called
* // with "changecolor" once() before.
* $(this).css('color', 'green');
* });
*
* @see removeOnce
* @see findOnce
*
* @public
* @global
*/
$.fn.once = function (id, fn) {
if (typeof id !== 'string') {
// Generate a numeric ID if the id passed can't be used as a CSS class.
if (!(id in cache)) {
cache[id] = ++uuid;
}
// When the fn parameter is not passed, we interpret it from the id.
if (!fn) {
fn = id;
}
id = cache[id];
}
// Filter the elements by which do not have the data yet.
var name = 'jquery-once-' + id;
var elements = this.filter(function() {
return $(this).data(name) !== true;
}).data(name, true);
return $.isFunction(fn) ? elements.each(fn) : elements;
};
/**
* Removes the once data from the given elements, based on the given ID.
*
* @param {string} id
* A required string representing the name of the data id which should be used
* when filtering the elements. This only filters elements that have already
* been processed by the once function. The id should be the same id that
* was originally passed to the once() function.
* @param {function} [fn]
* (Optional) If given, this function will be called for each element that
* whose element's once data was removed. The function's return value
* follows the same logic as $.each(). Returning true will continue to the
* next matched element in the set, while returning false will entirely
* break the iteration.
*
* @returns jQuery element collection of elements that now have their once
* data removed.
*
* @example
* // Remove once data with the "changecolor" ID.
* $('p').removeOnce('changecolor', function() {
* // This function is called for all elements that had their once removed.
* });
*
* @see once
*
* @public
* @global
*/
$.fn.removeOnce = function (id, fn) {
// Filter through the elements to find the once'd elements.
var elements = this.findOnce(id);
// Remove the once data from the elements.
elements.removeData('jquery-once-' + id);
return $.isFunction(fn) ? elements.each(fn) : elements;
};
/**
* Filters elements that have already been processed once.
*
* @param {string} id
* A required string representing the name of the data id which should be used
* when filtering the elements. This only filters elements that have already
* been processed by the once function. The id should be the same id that
* was originally passed to the once() function.
* @param {function} [fn]
* (Optional) If given, this function will be called for each element that
* has not yet been processed. The function's return value follows the same
* logic as $.each(). Returning true will continue to the next matched
* element in the set, while returning false will entirely break the
* iteration.
*
* @returns jQuery element collection of elements that have been run once.
*
* @example
* // Find all elements that have the changecolor'ed once.
* $('p').findOnce('changecolor', function() {
* // This function is called for all elements that has already once'd.
* });
*
* @see once
*
* @public
* @global
*/
$.fn.findOnce = function (id, fn) {
// Filter the elements by which do have the data.
var name = 'jquery-once-' + id;
var elements = this.filter(function() {
return $(this).data(name) === true;
});
return $.isFunction(fn) ? elements.each(fn) : elements;
};
}));
|