Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
227 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
/* | ||
* Watch Event Listener | ||
* | ||
* @author Darcy Clarke | ||
* Modified by Penn Su | ||
* | ||
* Copyright (c) 2014 Darcy Clarke | ||
* Dual licensed under the MIT and GPL licenses. | ||
* | ||
* Usage: | ||
* watch(element, 'width height', function(){ | ||
* console.log(this.style.width, this.style.height); | ||
* }); | ||
*/ | ||
|
||
(function (window) { | ||
|
||
var toArray; | ||
var eqlArrays; | ||
|
||
// http://jsfiddle.net/moagrius/YxzfV/ | ||
Array.prototype.multisplice = function(){ | ||
var args = Array.apply(null, arguments); | ||
args.sort(function(a,b){ | ||
return a - b; | ||
}); | ||
for(var i = 0; i < args.length; i++){ | ||
var index = args[i] - i; | ||
this.splice(index, 1); | ||
} | ||
} | ||
|
||
// Object to Array | ||
toArray = function (obj) { | ||
|
||
var arr = []; | ||
|
||
for (var i = obj.length >>> 0; i--;) { | ||
arr[i] = obj[i]; | ||
} | ||
|
||
return arr; | ||
|
||
}; | ||
|
||
eqlArrays = function (a, b) { | ||
a.length == b.length && a.every(function (e, i) { e === b[i] }); | ||
} | ||
|
||
var _watch = function (elements, props, options, callback){ | ||
|
||
// Setup | ||
var self = this; | ||
var check; | ||
|
||
// Check if we should fire callback | ||
check = function (e) { | ||
|
||
var self = this; | ||
|
||
for (var i = 0; i < self.watching.length; i++) { | ||
|
||
var data = self.watching[i]; | ||
var changed = true; | ||
var temp; | ||
|
||
// Iterate through properties | ||
for (var j = 0; j < data.props.length; j++) { | ||
temp = self.attributes[data.props[j]] || self.style[data.props[j]]; | ||
if (data.vals[j] != temp) { | ||
data.vals[j] = temp; | ||
data.changed[j] = true; | ||
} | ||
} | ||
|
||
// Check changed attributes | ||
for (var k = 0; k < data.props.length; k++) { | ||
if (!data.changed[k]) { | ||
changed = false; | ||
break; | ||
} | ||
} | ||
|
||
// Run callback if property has changed | ||
if (changed && data.callback) { | ||
data.callback.apply(self, e); | ||
} | ||
|
||
}; | ||
|
||
}; | ||
|
||
// Elements from node list to array | ||
elements = toArray(elements); | ||
|
||
// Type check options | ||
if (typeof(options) == 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
|
||
// Type check callback | ||
if (typeof(callback) != 'function') { | ||
callback = function(){}; | ||
} | ||
|
||
// Set throttle | ||
options.throttle = options.throttle || 10; | ||
|
||
// Iterate over elements | ||
for (var i = 0; i < elements.length; i++) { | ||
|
||
var element = elements[i]; | ||
var data = { | ||
props: props.split(' '), | ||
vals: [], | ||
changed: [], | ||
callback: callback | ||
}; | ||
|
||
// Grab each property's initial value | ||
for (var j = 0; j < data.props.length; j++) { | ||
data.vals[j] = element.attributes[data.props[j]] || element.style[data.props[j]]; | ||
data.changed[j] = false; | ||
} | ||
|
||
// Set watch array | ||
if (!element.watching) { | ||
element.watching = []; | ||
} | ||
|
||
// Store data in watch array | ||
element.watching.push(data); | ||
|
||
// Create new Mutation Observer | ||
var observer = new MutationObserver(function (mutations) { | ||
console.log(mutations); | ||
for (var k = 0; k < mutations.length; k++) { | ||
check.call(mutations[k].target, mutations[k]); | ||
} | ||
}); | ||
|
||
// Set observer array | ||
if (!element.observers) { | ||
element.observers = []; | ||
} | ||
|
||
// Store element observer | ||
element.observers.push(observer); | ||
|
||
// Start observing | ||
observer.observe(element, { subtree: false, attributes: true }); | ||
|
||
} | ||
|
||
// Return elements to enable chaining | ||
return self; | ||
|
||
}; | ||
|
||
var _unwatch = function (elements, props){ | ||
|
||
// Setup | ||
var self = this; | ||
|
||
// Elements from node list to array | ||
elements = toArray(elements); | ||
|
||
// Iterate over elements | ||
for (var i = 0; i < elements.length; i++) { | ||
|
||
var element = elements[i]; | ||
var indexes = [] | ||
|
||
for (var j = 0; j < element.watching.length; j++) { | ||
|
||
var data = element.watching[j]; | ||
if (eqlArrays(data.props, props.split(' '))) { | ||
indexes.push(j); | ||
} | ||
|
||
} | ||
|
||
element.watching.multisplice.apply(element.watching, indexes); | ||
|
||
} | ||
|
||
// Return elements to enable chaining | ||
return self; | ||
|
||
}; | ||
|
||
// Expose watch to window | ||
window.watch = function () { | ||
return _watch.apply(arguments[0], arguments); | ||
}; | ||
|
||
window.unwatch = function () { | ||
return _unwatch.apply(arguments[0], arguments); | ||
}; | ||
|
||
// Expose watch to jQuery | ||
(function ($) { | ||
$.fn.watch = function () { | ||
Array.prototype.unshift.call(arguments, this); | ||
return _watch.apply(this, arguments); | ||
}; | ||
|
||
$.fn.unwatch = function () { | ||
Array.prototype.unshift.call(arguments, this); | ||
return _unwatch.apply(this, arguments); | ||
}; | ||
})(jQuery); | ||
|
||
})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters