/* Cross Browser Watch Function */
Object.prototype.xwatch = function (prop,func){
if(!Object.watch){
new IEwatch(this,prop,func);
}
else{
this.watch(prop,func);
}
}
var IEwatch = Class.create();
IEwatch.prototype = {
initialize: function(obj,prop,func){
this.obj = obj;
this.prop = prop;
this.func = func;
this.oldvalue = this.obj[this.prop];
setInterval(this.check.bind(this),50);
},
check : function(){
if(this.obj[this.prop] != null && this.obj[this.prop] != this.oldvalue){
this.oldvalue=this.func(this.prop,this.oldvalue,this.obj[this.prop]);
}
}
}
First, I start off by extending the Object Class by adding a new method called xwatch (cross-browser watch). If the browser supports watch() then the native function is used otherwise my IEwatch method is used. IEwatch polls the variable specified looking for a change in the variable's value. Kinda crude but it works. I haven't run into any problems with race situations yet.
I also created the function below to bind a JS variable to another Object. You could use it to bind a variable to a text input or the innerHTML property of a div etc etc.
/* Data Bind Functions */
var dataBinding = Class.create();
dataBinding.prototype = {
initialize: function(sourceObj, sourceProp, destinationObj, destinationProp){
this.srcObj=sourceObj;
this.srcProp=sourceProp;
this.destObj=destinationObj;
this.destProp=destinationProp;
var temp = this.update(this.sourceProp, this.srcObj[this.srcProp],this.srcObj[this.srcProp]);
this.create();
},
create: function(){
this.srcObj.xwatch(this.srcProp,this.update.bind(this));
},
update: function(id, oldvalue, newvalue){
this.destObj[this.destProp] = newvalue;
return newvalue;
}
}
Note, these Classes required prototype.js to function.
2 comments:
Here's my version of your code, with watching and unwatching, and the only Prototype method used is bind, which can be replaced with an anonymous function. It uses closures instead of Classes. Also, function isset is below.
function isset(ref) { return ref.toString ? ref.toString().toLowerCase() !== "undefined" : false; }
Object.prototype.xwatch = function (prop, func) {
if (!Object.watch) { this.watchpoint = new IEwatch(this, prop, func); }
else { this.watch(prop, func); }
};
Object.prototype.xunwatch = function (prop) {
if (!Object.unwatch) {
if (this.watchpoint) {
this.watchpoint.unwatch();
delete(this.watchpoint);
}
} else { this.unwatch(prop); }
}
var IEwatch = function (obj, prop, func) {
prop = String(prop);
var _oldvalue, _interval,
self = {
setup: function () {
_oldvalue = obj[prop];
_interval = window.setInterval(self.check.bind(self), 50);
},
check: function () {
if (isset(typeof(obj[prop])) && obj[prop] !== null && obj[prop] !== _oldvalue) {
_oldvalue = func(prop, _oldvalue, obj[prop]);
}
},
unwatch: function () { window.clearInterval(_interval); }
};
if (typeof(func)==="function") { self.setup(); }
return self;
};
IE supports the onpropertychange custom event for Microsoft Behavior/HTC elements. That is one way to emulate the watch() method there.
Post a Comment