Forum Moderators: open
I think this is the best way to achieve what I'm trying to do, as each element can then operate independantly of each other, and I don't have to keep a huge list in the background tying elements to their variables.
For the example I'll use 2 images. They're not actually there that's not important.
function myClass( val) {
this.myVal = val;
}
myClass.prototype.hello = function() { alert( this.val); }
var myImgs = document.getElementsByTagName( "IMG");
myImgs[0].myClass = new myClass( "FOO!");
myImgs[1].myClass = new myClass( "BAR!");
So I have a class with 1 function that pops up a value. If I call this manually it works fine. Memory wise this is ok right? There will only be 1 copy of the hello function, but 2 separate values for myVal?
The problem occurs when I'm trying to assign the function to an event, using addEvent (or anything else).
addEvent( myImgs[0], "click", WHAT SHOULD GO HERE?);
If I use this:
addEvent( myImgs[0], "click", function() { this.myClass.hello(); }); The function fires ok, but this refers to the calling function, not the element, and myVal ends up undefined. If I call the function manually the myVal is ok.
Am I over-classing this? Is there really a point in adding the functions into the class, or should I just keep the functions separate?
For example, instead of adding a myClass property to each img element, you could do something like this:
var myImgs = document.getElementsByTagName("IMG");
myObj[0] = new myClass("FOO");
addEvent(myImgs[0], "click", myObj[0].hello);
In that example, it's a very loose relationship between the element and the object you're creating, with the addEvent method tying them together. It doesn't look like you're accessing any properties of the img element so I don't see a need to create your object within the scope of an img element.
Note, this example was meant to simply show how you could store them separately. The callback to "hello" would still not have the scope of myClass, but you could do this instead:
YAHOO.util.Event.on(myImgs[0], "click", myObj[0].hello, myObj[0], true );
They let you specify the scope
So how does that work then?
I am particularly interested to know that, it would be very handy for something else I'm working on....
Although now I know what I'm looking for I can probably Google it.
advantage do you see in attaching the objects directly to the DOM vs. storing them in your own object/array?
Not having my own object/array, and then having to find this particular object within that array.
You have to admit, knowing that 'this' will always mean the object in question, that is a whole lot easier?
It doesn't look like you're accessing any properties of the img element
That was just an example. I plan to attach to INPUT tags for the other script in progress. So it would access the name and value properties, and also store it's own validation settings.
function addEvent(el, ev, cb, scopeObj) {
//...
if (!scopeObj) {
scopeObj = el;
}
var wrapper = function() {
return cb.call(scopeObj);
});
addListener(el, ev, wrapper);
Note, that is a very bare bones example. I didn't perform any cross browser checks (this example will fail in IE). But hopefully that gives you an understanding of the basic concept.
You have to admit, knowing that 'this' will always mean the object in question, that is a whole lot easier?
function foo(a, b) {
alert('#'+a+'#:*'+b+'*');
}
foo.call(window, 'x', 'y');
foo.apply(window, ['x', 'y']);
The reason my earlier example wouldn't work is because I called addListener... I would need to add some logic to determine whether I could call addListener or if I had to call attachEvent, since one method only works in standards compliant browsers and the other only works in IE.
[edited by: Fotiman at 6:13 pm (utc) on Oct. 1, 2008]
Call takes individual parameters as the arguments, apply takes an array as the 2nd paramter which represents the arguments
Yeah I saw that when I looked them up. Seems strange to have 2 functions though that do exactly the same thing. Nevermind.
because I called addListener
Oh I didn't spot that. I thought there was a problem with using call itself.
Thanks again for that one Foti!