My current project at work consists of eight server side developers that have very little JavaScript/DOM experience. We are implementing some new AJAX features and I wanted to find a simple way to update the data on the page without having to use the methods of the DOM. I was happy to find the Mozilla __defineGetter__ and __defineSetter__ methods. These methods allow you to override the accessor and mutator methods for a property.
The good
The mutator methods of an object can be redefined to update the DOM when a property is set.
document.attachToDOM = function(obj) {
for (var varname in obj) {
id (document.getElementById(varname)) {
setter = function(val) {
var elem =
document.getElementById(varname);
// update text node of element
}
setter.varname = varname;
setter.obj = obj;
obj.__defineSetter__(varname, setter);
}
}
}
The above method iterates over the properties of an object. If it finds a DOM element with an id that matches the name of the property, it overrides the setter of that property to update the related DOM element. My implementation replaced all descendant nodes of the element with a text node that contained the new value of the property. If the related node was an input element such as a text box, it would insert the value into the input control instead of replacing the descendant nodes. So once and object is attached to the DOM, all the AJAX developer has to do is set the object property to the desired value.
<span id="price"></span><script type="text/javascript">
// imagine an Item object is defined
// elsewhere and has a price attribute
var itemObj = new Item();
document.attachToDOM(itemObj);
itemObj.price = '4.25';
</script>
The contents of the span would now be:
<span id="price">4.25</span>
The bad
The worst thing about the __defineGetter__ and __defineSetter methods is that they are not supported by Internet Explorer, rendering them virtually useless in real world development. The other issue is that most JavaScript implementations do not allow recursion. In order to store the property in the object with the overridden accessors/mutators you have to save the value to the property. However, since you have overridden the mutators, setting the property will make another call to the overridden method...and you have recursion! The best solution I've come up with for this is to maintain a reference to a copy of the object that is being retooled. You can then store the values in this object, thus avoiding the recursion problem.