Skip to content

Instantly share code, notes, and snippets.

@sagebind
Created May 25, 2017 15:19
Show Gist options
  • Save sagebind/56c0a89222bf089b1ddcc9fc9321e0cf to your computer and use it in GitHub Desktop.
Save sagebind/56c0a89222bf089b1ddcc9fc9321e0cf to your computer and use it in GitHub Desktop.
Function that watches the property of any object for changes.
/**
* Standalone function used to continuously watch the property of an object for changes.
*
* The function is as optimized as possible to reduce needless timeout and interval callbacks, but this should still be
* used sparingly and only when events are not possible.
*
* Usage:
* var item = watch(someObject, "propertyName", function(oldValue, newValue, cancel) {
* // Handle the change here.
* // Optionally cancel watching.
* cancel();
* });
*
* // You can also cancel with the return value.
* item.cancel();
*/
window.watch = (function() {
var watchList = [], timer = null, timerResolution = 500;
function WatchItem(object, property, callback) {
this.object = object;
this.property = property;
this.callback = callback;
this.active = true;
this.oldValue = object[property];
}
WatchItem.prototype.cancel = function() {
this.active = false;
var index = watchList.indexOf(this);
if (index >= 0) {
watchList.splice(index, 1);
}
if (watchList.length === 0) {
clearInterval(timer);
timer = null;
}
};
function sentinel() {
for (var i = 0; i < watchList.length; ++i) {
var item = watchList[i];
var newValue = item.object[item.property];
if (newValue !== item.oldValue) {
item.callback(item.oldValue, newValue, item.cancel);
}
if (!item.active) {
--i;
}
item.oldValue = newValue;
}
}
return function(object, property, callback) {
var item = new WatchItem(object, property, callback);
watchList.push(item);
if (timer === null) {
timer = setInterval(sentinel, timerResolution);
}
return item;
};
})();
@sagebind
Copy link
Author

Don't use this, it's bad for performance and not very responsive. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment