Commit c94a2306bcbf72329a9977b929867e809102329f
1 parent
2e9ab843
Exists in
master
and in
1 other branch
Adding livequery plugin.
Showing
1 changed file
with
250 additions
and
0 deletions
Show diff stats
... | ... | @@ -0,0 +1,250 @@ |
1 | +/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net) | |
2 | + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | |
3 | + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. | |
4 | + * | |
5 | + * Version: 1.0.3 | |
6 | + * Requires jQuery 1.1.3+ | |
7 | + * Docs: http://docs.jquery.com/Plugins/livequery | |
8 | + */ | |
9 | + | |
10 | +(function($) { | |
11 | + | |
12 | +$.extend($.fn, { | |
13 | + livequery: function(type, fn, fn2) { | |
14 | + var self = this, q; | |
15 | + | |
16 | + // Handle different call patterns | |
17 | + if ($.isFunction(type)) | |
18 | + fn2 = fn, fn = type, type = undefined; | |
19 | + | |
20 | + // See if Live Query already exists | |
21 | + $.each( $.livequery.queries, function(i, query) { | |
22 | + if ( self.selector == query.selector && self.context == query.context && | |
23 | + type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) ) | |
24 | + // Found the query, exit the each loop | |
25 | + return (q = query) && false; | |
26 | + }); | |
27 | + | |
28 | + // Create new Live Query if it wasn't found | |
29 | + q = q || new $.livequery(this.selector, this.context, type, fn, fn2); | |
30 | + | |
31 | + // Make sure it is running | |
32 | + q.stopped = false; | |
33 | + | |
34 | + // Run it immediately for the first time | |
35 | + q.run(); | |
36 | + | |
37 | + // Contnue the chain | |
38 | + return this; | |
39 | + }, | |
40 | + | |
41 | + expire: function(type, fn, fn2) { | |
42 | + var self = this; | |
43 | + | |
44 | + // Handle different call patterns | |
45 | + if ($.isFunction(type)) | |
46 | + fn2 = fn, fn = type, type = undefined; | |
47 | + | |
48 | + // Find the Live Query based on arguments and stop it | |
49 | + $.each( $.livequery.queries, function(i, query) { | |
50 | + if ( self.selector == query.selector && self.context == query.context && | |
51 | + (!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped ) | |
52 | + $.livequery.stop(query.id); | |
53 | + }); | |
54 | + | |
55 | + // Continue the chain | |
56 | + return this; | |
57 | + } | |
58 | +}); | |
59 | + | |
60 | +$.livequery = function(selector, context, type, fn, fn2) { | |
61 | + this.selector = selector; | |
62 | + this.context = context || document; | |
63 | + this.type = type; | |
64 | + this.fn = fn; | |
65 | + this.fn2 = fn2; | |
66 | + this.elements = []; | |
67 | + this.stopped = false; | |
68 | + | |
69 | + // The id is the index of the Live Query in $.livequery.queries | |
70 | + this.id = $.livequery.queries.push(this)-1; | |
71 | + | |
72 | + // Mark the functions for matching later on | |
73 | + fn.$lqguid = fn.$lqguid || $.livequery.guid++; | |
74 | + if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++; | |
75 | + | |
76 | + // Return the Live Query | |
77 | + return this; | |
78 | +}; | |
79 | + | |
80 | +$.livequery.prototype = { | |
81 | + stop: function() { | |
82 | + var query = this; | |
83 | + | |
84 | + if ( this.type ) | |
85 | + // Unbind all bound events | |
86 | + this.elements.unbind(this.type, this.fn); | |
87 | + else if (this.fn2) | |
88 | + // Call the second function for all matched elements | |
89 | + this.elements.each(function(i, el) { | |
90 | + query.fn2.apply(el); | |
91 | + }); | |
92 | + | |
93 | + // Clear out matched elements | |
94 | + this.elements = []; | |
95 | + | |
96 | + // Stop the Live Query from running until restarted | |
97 | + this.stopped = true; | |
98 | + }, | |
99 | + | |
100 | + run: function() { | |
101 | + // Short-circuit if stopped | |
102 | + if ( this.stopped ) return; | |
103 | + var query = this; | |
104 | + | |
105 | + var oEls = this.elements, | |
106 | + els = $(this.selector, this.context), | |
107 | + nEls = els.not(oEls); | |
108 | + | |
109 | + // Set elements to the latest set of matched elements | |
110 | + this.elements = els; | |
111 | + | |
112 | + if (this.type) { | |
113 | + // Bind events to newly matched elements | |
114 | + nEls.bind(this.type, this.fn); | |
115 | + | |
116 | + // Unbind events to elements no longer matched | |
117 | + if (oEls.length > 0) | |
118 | + $.each(oEls, function(i, el) { | |
119 | + if ( $.inArray(el, els) < 0 ) | |
120 | + $.event.remove(el, query.type, query.fn); | |
121 | + }); | |
122 | + } | |
123 | + else { | |
124 | + // Call the first function for newly matched elements | |
125 | + nEls.each(function() { | |
126 | + query.fn.apply(this); | |
127 | + }); | |
128 | + | |
129 | + // Call the second function for elements no longer matched | |
130 | + if ( this.fn2 && oEls.length > 0 ) | |
131 | + $.each(oEls, function(i, el) { | |
132 | + if ( $.inArray(el, els) < 0 ) | |
133 | + query.fn2.apply(el); | |
134 | + }); | |
135 | + } | |
136 | + } | |
137 | +}; | |
138 | + | |
139 | +$.extend($.livequery, { | |
140 | + guid: 0, | |
141 | + queries: [], | |
142 | + queue: [], | |
143 | + running: false, | |
144 | + timeout: null, | |
145 | + | |
146 | + checkQueue: function() { | |
147 | + if ( $.livequery.running && $.livequery.queue.length ) { | |
148 | + var length = $.livequery.queue.length; | |
149 | + // Run each Live Query currently in the queue | |
150 | + while ( length-- ) | |
151 | + $.livequery.queries[ $.livequery.queue.shift() ].run(); | |
152 | + } | |
153 | + }, | |
154 | + | |
155 | + pause: function() { | |
156 | + // Don't run anymore Live Queries until restarted | |
157 | + $.livequery.running = false; | |
158 | + }, | |
159 | + | |
160 | + play: function() { | |
161 | + // Restart Live Queries | |
162 | + $.livequery.running = true; | |
163 | + // Request a run of the Live Queries | |
164 | + $.livequery.run(); | |
165 | + }, | |
166 | + | |
167 | + registerPlugin: function() { | |
168 | + $.each( arguments, function(i,n) { | |
169 | + // Short-circuit if the method doesn't exist | |
170 | + if (!$.fn[n]) return; | |
171 | + | |
172 | + // Save a reference to the original method | |
173 | + var old = $.fn[n]; | |
174 | + | |
175 | + // Create a new method | |
176 | + $.fn[n] = function() { | |
177 | + // Call the original method | |
178 | + var r = old.apply(this, arguments); | |
179 | + | |
180 | + // Request a run of the Live Queries | |
181 | + $.livequery.run(); | |
182 | + | |
183 | + // Return the original methods result | |
184 | + return r; | |
185 | + } | |
186 | + }); | |
187 | + }, | |
188 | + | |
189 | + run: function(id) { | |
190 | + if (id != undefined) { | |
191 | + // Put the particular Live Query in the queue if it doesn't already exist | |
192 | + if ( $.inArray(id, $.livequery.queue) < 0 ) | |
193 | + $.livequery.queue.push( id ); | |
194 | + } | |
195 | + else | |
196 | + // Put each Live Query in the queue if it doesn't already exist | |
197 | + $.each( $.livequery.queries, function(id) { | |
198 | + if ( $.inArray(id, $.livequery.queue) < 0 ) | |
199 | + $.livequery.queue.push( id ); | |
200 | + }); | |
201 | + | |
202 | + // Clear timeout if it already exists | |
203 | + if ($.livequery.timeout) clearTimeout($.livequery.timeout); | |
204 | + // Create a timeout to check the queue and actually run the Live Queries | |
205 | + $.livequery.timeout = setTimeout($.livequery.checkQueue, 20); | |
206 | + }, | |
207 | + | |
208 | + stop: function(id) { | |
209 | + if (id != undefined) | |
210 | + // Stop are particular Live Query | |
211 | + $.livequery.queries[ id ].stop(); | |
212 | + else | |
213 | + // Stop all Live Queries | |
214 | + $.each( $.livequery.queries, function(id) { | |
215 | + $.livequery.queries[ id ].stop(); | |
216 | + }); | |
217 | + } | |
218 | +}); | |
219 | + | |
220 | +// Register core DOM manipulation methods | |
221 | +$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove'); | |
222 | + | |
223 | +// Run Live Queries when the Document is ready | |
224 | +$(function() { $.livequery.play(); }); | |
225 | + | |
226 | + | |
227 | +// Save a reference to the original init method | |
228 | +var init = $.prototype.init; | |
229 | + | |
230 | +// Create a new init method that exposes two new properties: selector and context | |
231 | +$.prototype.init = function(a,c) { | |
232 | + // Call the original init and save the result | |
233 | + var r = init.apply(this, arguments); | |
234 | + | |
235 | + // Copy over properties if they exist already | |
236 | + if (a && a.selector) | |
237 | + r.context = a.context, r.selector = a.selector; | |
238 | + | |
239 | + // Set properties | |
240 | + if ( typeof a == 'string' ) | |
241 | + r.context = c || document, r.selector = a; | |
242 | + | |
243 | + // Return the result | |
244 | + return r; | |
245 | +}; | |
246 | + | |
247 | +// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091) | |
248 | +$.prototype.init.prototype = $.prototype; | |
249 | + | |
250 | +})(jQuery); | |
0 | 251 | \ No newline at end of file | ... | ... |