Hi,

> The question is, how can I pass the currentElement value to that
> pseudo function?

It's not a psuedo-function, it's a function.  It's anonymous, but
other than that it's exactly the same as any other function.

I'm not saying that to be pedantic.  Getting a deep understanding
JavaScript functions is one of the keys to really using the language
well.

In your code, you're calling setTimeout in a loop, and within that
loop (on each iteration) you're creating a function to pass into
setTimeout.  You're expecting that that function will receive a frozen
copy of the value of the currentElement variable, and so will refer to
the element for that iteration of the loop.  That's where things are
going wrong, because that's not what the function receives.  (Don't
worry, *lots* of people make that mistake, it's all part of the
learning curve.)

When a function is created within a scope (such as within another
function), it receives a *live* reference (not a frozen copy) of all
of the variables in that scope.  So all of the copies of your
function, when they run, will try to use the value "pic50" -- which
doesn't exist, as you have pic0 through pic49.  Why?  Because by the
time they use the currentElement variable, it has the value 50.

Try this little experiment to see this effect in action:

function foo() {
    var a;

    a = 5;

    setTimeout(function() { alert("a = " + a); }, 500);

    a = 6;
}

If you run foo(), you'll see "a = 6", not "a = 5".  Freaky, huh, since
foo() has long since returned.  'a' still exists because the anonymous
function has a reference to it (indirectly, because it has a reference
to the "variable object" that contains all of foo's variables -- even
ones that nothing will ever use again).

This is one of the most powerful features of JavaScript.  Search for
"JavaScript closure" to find more about it; I've also written up a bit
about closures here:
http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
http://blog.niftysnippets.org/2008/03/closures-by-example.html

What I'd suggest in your situation is write a named function that does
what you want, and accepts a parameter giving the ID to perform the
work on.  Something like this:

function applyOpacityEffect(id) {
    new Effect.Opacity(id, {duration:0.2, from:0.2, to:1} );
}

...although you can probably make it more general than that, and then
use Function#delay[1] to call it after half a second's delay:

this.timeout = applyOpacityEffect.delay(0.5, currentElement);

[1] http://prototypejs.org/api/function/delay

It doesn't have to be a named function, but it will tend to make the
code clearer.

Have fun!

HTH,
--
T.J. Crowder
tj / crowder software / com
Independent Software Engineer, consulting services available


On Mar 5, 10:43 am, DasJan <jro...@gmail.com> wrote:
> Hi!
>
> I have the following code:
>
> var LightIt = {
>     timeout : null,
>     highLight : function(elementId){
>         clearTimeout(this.timeout);
>         var allpics = 50;
>         for (var i=0; i < allpics; i++) {
>                 var currentElement = 'pic' + i;
>                                 var dummyElement = 'dummy' + i;
>
>                                 if($(elementId).style.opacity == 1){
>                         if(document.getElementById(currentElement) != null) {
>                                 if(currentElement != elementId) {
>                           this.timeout = setTimeout(function(){new 
> Effect.Opacity
> (currentElement, {duration:0.2, from:1, to:0.2} )},400);
>                                 }
>                         }
>                         if(document.getElementById(dummyElement) != null) {
>                                   this.timeout = setTimeout(function(){new 
> Effect.Opacity
> (dummyElement, {duration:0.2, from:1, to:0.2})},400);
>                         }
>                 }
>         }
>     },
>     unhighLight : function(elementId){
>         if($(elementId).style.opacity == 1){
>             clearTimeout(this.timeout);
>         }else{
>                 var allpics = 50;
>                                 for (var i=0; i < allpics; i++) {
>                                 var currentElement = 'pic' + i;
>                                                 var dummyElement = 'dummy' + 
> i;
>
>                                         
> if(document.getElementById(currentElement) != null) {
>                                                 if(currentElement != 
> elementId) {
>                                         this.timeout = 
> setTimeout(function(){new Effect.Opacity
> ( currentElement, {duration:0.2, from:0.2, to:1} )},400);
>                                                 }
>                                         }
>                                         
> if(document.getElementById(dummyElement) != null) {
>                                                 this.timeout = 
> setTimeout(function(){new
> Effect.Opacity( dummyElement, {duration:0.2, from:0.2, to:1} )},400);
>                                         }
>                                 }
>         }
>     }
>
> }
>
> That code is called by onmouseover="LightIt.highLight('pic1');" and
> onmouseout="LightIt.unhighLight('pic1');".
>
> However my Firebug console displays the following error:
>
> "uncaught exception: [object Object]"
>
> I have have figured out that the problem is this part:
>
>  this.timeout = setTimeout(function(){new Effect.Opacity
> (currentElement, {duration:0.2, from:1, to:0.2} )},400);
>
> The "currentElement" in there seems to be empty, because the value is
> not passed to the pseudo function. To see if the script work I did
> this:
>
>  this.timeout = setTimeout(function(){new Effect.Opacity('pic1',
> {duration:0.2, from:1, to:0.2} )},400);
>
> When I directly write the element name into the script it works
> perfectly.
>
> The question is, how can I pass the currentElement value to that
> pseudo function?
>
> Thanks,
> Jan
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptaculous@googlegroups.com
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to