This demo presents different implementations of a TriStateImage object. They illustrate different techniques for associating user-defined objects with Element objects.
Our specification is for the objects to implement a 3-state rollover effect on an IMG element, given the IMG element's id, a URL to a mouseover image file, a URL to a mousedown image file, and a mouseup event listener function reference. The mouseout image is taken from the IMG element's src attribute.
Mike Foster, 4 Sep 2004, 6 Mar 2005, 11 May 2005
TriStateImageFactory:
TriStateImageClass:
The onload event listener tests the different techniques.
var btn1, btn2; window.onload = function() { btn1 = TriStateImageFactory('img1', '../graphics/cat_wake.jpg', '../graphics/cat_wake_neg.jpg', catOnMouseup); btn2 = new xTriStateImage('img2', '../graphics/scope_day.jpg', '../graphics/scope_day_neg.jpg', scopeOnMouseup); if (btn1 && btn2) { // continue application initialization } } window.onunload = function() { btn2.onunload(); } function catOnMouseup() { //... } function scopeOnMouseup() { //... }
Technique 1 is similar to the 'Factory Pattern'. A function returns an object. The function is not an object prototype - we do not create object instances with the 'new' operator. We simply call the function and it returns a reference to an object.
In this demo I do not create a user-defined object in the conventional sense. I add custom properties to an existing Element object, and then return a reference to that Element object.
function TriStateImageFactory(idOut, urlOver, urlDown, fnUp) { // Downgrade Detection if (typeof Image != 'undefined' && document.getElementById) { var img = document.getElementById(idOut); if (img) { // Add custom properties img.fnUp = fnUp; img.urlOut = img.src; img.imgOver = new Image(); img.imgOver.src = urlOver; img.imgDown = new Image(); img.imgDown.src = urlDown; // Add event listeners img.onmouseover = tsiOnMouseover; img.onmouseout = tsiOnMouseout; img.onmousedown = tsiOnMousedown; img.onmouseup = tsiOnMouseup; return img; } } return null; } // Event Listeners function tsiOnMouseover() { this.src = this.imgOver.src; } function tsiOnMouseout() { this.src = this.urlOut; } function tsiOnMousedown() { this.src = this.imgDown.src; } function tsiOnMouseup() { this.src = this.imgOver.src; if (this.fnUp) { this.fnUp(); } }
Technique 2 is an object prototype, similar to a 'class', from which we will create instances via the 'new' operator. This technique uses 'closure' to allow the Element event listeners to have access to the user-defined object instance properties. This technique provides for 'private' properties. Also note that the event listeners have access to the arguments passed to the object prototype.
function xTriStateImage(idOut, urlOver, urlDown, fnUp) // Object Prototype { var img; // Downgrade Detection if (typeof Image != 'undefined' && document.getElementById) { img = document.getElementById(idOut); if (img) { // Constructor Code var urlOut = img.src; var i = new Image(); i.src = urlOver; i = new Image(); i.src = urlDown; // Event Listeners (closure) img.onmouseover = function() { this.src = urlOver; }; img.onmouseout = function() { this.src = urlOut; }; img.onmousedown = function() { this.src = urlDown; }; img.onmouseup = function() { this.src = urlOver; if (fnUp) { fnUp(); } }; } } // Destructor Method this.onunload = function() { if (xIE4Up && img) { // Remove any circular references for IE img.onmouseover = img.onmouseout = img.onmousedown = null; img = null; } }; }
View the latest src/docs for xTriStateImage.
By your use of X and/or CBE and/or any Javascript from this site you consent to the GNU LGPL - please read it. If you have any questions about the license, read the FAQ and/or come to the forums.
Forum support is available at the X Library Support Forums.