I need to fire an event every time a property is updated/changed in order to keep dom elements in sync with the property values on the model (Im using john resig's simple inheritance http://ejohn.org/blog/simple-javascript-inheritance/). Is this possible to do in a cross-browser way? It seems to me that if I could wrap whatever function js uses to set properties and make it fire an event, that it could work, Im just not sure how to do that.
4 Answers
JavaScript doesn't use a function to set properties. They're just variables, and setting them doesn't require any elaborate wrappers.
You could use a function to set the property, though — the same sort of a getter/setter arrangement you might use in a language that supported private data in classes. In that way your function could easily run other functions that have been registered as callbacks. Using jQuery you can even handle those as events.
$(yourObject).bind('some-event-you-made-up', function() {
// This code will run whenever some-event-you-made-up is triggered on yourObject
});
// ...
$(yourObject).trigger('some-event-you-made-up');

- 37,319
- 5
- 97
- 97
-
3It is actually possible to have "getter" and "setter" functions for object properties in the Mozilla-extended Javascript. – Pointy Nov 12 '10 at 22:44
-
The problem is that the object that I want to listen for the event is not a jquery object, just a generic object that is stored in the jquery objects data object. I don't know how to bind an event to it. – joshontheweb Nov 12 '10 at 23:09
-
1Exactly as I showed. `yourObject` can be whatever you want. It's got nothing to do with jQuery. You're then using jQuery to merely keep track of all the callback functions you might bind to `yourObject`. – VoteyDisciple Nov 12 '10 at 23:14
-
@GuilhermeFerreira This question and answer are from seven years ago, predating `Object.defineProperty`. I certainly encourage you to write up an appropriate answer for 2017 if you feel the question would still benefit from it. – VoteyDisciple Jul 22 '17 at 02:44
Object defineProperty/defineProperties does the trick. Here goes a simple code. I have built some data binding frameworks based on that, and it can get really complex, but for exercising its like this:
var oScope = {
$privateScope:{},
notify:function(sPropertyPath){
console.log(sPropertyPath,"changed");
}
};
Object.defineProperties(oScope,{
myPropertyA:{
get:function(){
return oScope.$privateScope.myPropertyA
},
set:function(oValue){
oScope.$privateScope.myPropertyA = oValue;
oScope.notify("myPropertyA");
}
}
});
oScope.myPropertyA = "Some Value";
//console will log: myPropertyA changed

- 2,209
- 21
- 23
Maybe you already solved your problem with jQuery bind/trigger, but I wanted to tell that I'm building a Change Tracking and (in top of that) Entity Modeling Javascript Framework, named "tent" that solves the problem you exposed, without requiring any special syntax on object manipulation, its open source and hosted at:
https://github.com/benjamine/tent
It's documented with JSDoc and unit tested with js-test-driver.
you can use the change tracking module this way:
var myobject = { name: 'john', age: 34 };
// add a change handler that shows changes on alert dialogs
tent.changes.bind(myobject, function(change) {
alert('myobject property '+change.data.propertyName+' changed!');
});
myobject.name = 'charly'; // gets notified on an alert dialog
it works with Array changes too (adds, deletes). Further you can use "Entity" Contexts to keep a changesets of all detected changes (ADDED, DELETED, MODIFIED items) grouped on collections, cascade adds and deletes, keep reverse properties synced, track 1-to-1, 1-to-N and N-to-M relationships, etc.

- 4,099
- 1
- 30
- 31
You could try Javascript Property Events (jpe.js)
I encountered a similar issue, and ended up writing an overload function for Object.defineProperty that adds event handlers to the properties. It also provides type checking (js-base-types) and stores its value internally, preventing unwanted changes.
Sample of normal defineProperty:
Object.defineProperty(document, "property", {
get:function(){return myProperty},
set:function(value){myProperty = value},
})
var myProperty = false;
Sample of property with onchange event:
Object.defineProperty(document, "property", {
default:false,
get:function(){},
set:function(value){},
onchange:function(event){console.info(event)}
})

- 69
- 4
-
1i was shocked to see an "onchange" event in there, but only later i saw it is a framework haha – Guilherme Ferreira Jul 22 '17 at 04:04