Wednesday, August 27, 2008

JavaScript DOM property listeners

Here's a scenario.... Say we have an image on an HTML page that can be dragged and dropped anywhere within the browser window. Now, we need to perform some operations such as displaying the current location of the image as soon as the position of the image changes. The most common way of changing the position of an element in JavaScript is by modifying its style attribute's "top" and "left" properties. Now, we can detect such modifications in most current browsers by using functions available on the DOM elements. The syntax and working of these events is very different between the various browsers but suffice for most situations.

Basically, IE supports the "onpropertychange" event on DOM elements while FF and Opera support the "DOMAttrModified" event. Here's some sample code that's been tested in IE7, FF2 and Opera 9.5, that illustrates how these events can be used. Safari has no equivalent event in its repertoire, so the code below doesn't work in it at the moment.

function changeDivAttrs(){
var div = $("testDiv");
div.style.borderColor = "green";
}
function setWatches(){
var div = $("testDiv");
if(browser.IE)
div.setAttribute("onpropertychange",handleChange);
else
div.addEventListener("DOMAttrModified",
handleChange,false);
}
function handleChange(e){
if(browser.IE) {
//comment this line to view all attributes affected
if(event.propertyName == "style.borderColor")
showMessage(event.srcElement,
event.srcElement.id,
event.propertyName);
}
else //Firefox and Opera
showMessage(e.target,e.target.id,e.attrName);
}
function showMessage(element,id,propertyName){
alert(element + ":" + id + ":" + propertyName);
}
//HTML Section
< body onload="setWatches()" >
< div id="testDiv"
style="border-color:red;
border-style:solid;
border-width:2px" >
Test DIV Container
< /div >
< input type="button" onclick="changeDivAttrs()"
value="Change" />
< /body >
FF and Opera return the property name as just "style" while IE returns "style.borderColor" (kudos to the IE developers, for once!!!). Also, FF and Opera really watch for just changes i.e. the event is fired only when the previous value of the attribute is different from the new value. IE, on the other hand, fires every time the property is set or reset, even if the value hasn't really been modified. Additionally, comment the check in the function "handleChange" to see that the properties "borderTopColor","borderRightColor","borderBottomColor" and "borderLeftColor" are also getting affected.

Cheers.

No comments: