views:

475

answers:

3

Hi, I can't get this For loop with onRollOver to work.

for (var i:Number = 1; i<=4; i++) {
 this['videobutton'+i].onRollOver = function() {
        trace(i);
  this['stream'+i].pause(false);
  this['video'+i].attachVideo(this['stream'+i]);
  fadeIn(this['video'+i]);
 };
}

It think it has to do with variable scope and the i, but I don't know how to fix it.

The trace gives me: 5

Any ideas?

Here's the source file: http://drop.io/gqdcyp3

Update
I solved it myself, but I don't think it's the optimal solution:

var videos:Array = new Array(
'ltp_video-low1.flv',
'ltp_video-low1.flv',
'ltp_video-low1.flv',
'ltp_video-low1.flv'
);

function videoOver(buttonMC,video,stream) {
 buttonMC.onRollOver = function() {
 stream.pause(false);
 video.attachVideo(stream);
 fadeIn(video);
 };
}

function videoOut(buttonMC,video,stream) {
 buttonMC.onRollOut = function() {
 fadeOut(video);
 stream.pause();
 };
}

for (var i:Number=1; i<=4; i++) {
 this['connection'+i] = new NetConnection();
 this['connection'+i].connect(null);
 this['stream'+i] = new NetStream(this['connection'+i]);
 this['stream'+i].play(videos[i-1]);
 videoOver(this['videobutton'+i],this['video'+i],this['stream'+i]);
 videoOut(this['videobutton'+i],this['video'+i],this['stream'+i]);
}

Anyhow, this works. But it would great if someone could give me a solution created from this, since it works. How can I have the functions in the loop?

+1  A: 

I haven't done anything with Flash before, but it looks like the variable i is being closed over. The code inside the rollover handler is only executed on rollover, and i is evaluated at that time; not at the time the function is defined.

By creating the handler function within another function, each handler should get its own i:

for (var i:Number = 1; i<=4; i++) {
        this['videobutton'+i].onRollOver = MakeRollOverHandler(i);
}

function MakeRollOverHandler(i:Number)
{
    return function()  {
        trace(i);
                this['stream'+i].pause(false);
                this['video'+i].attachVideo(this['stream'+i]);
                fadeIn(this['video'+i]);
        };
}

You'll probably have to adjust for ActionScript's syntax but the general idea should be sound assuming the function parameters are passed by value. Each invocation of MakeRollOverHandler will create a distinct i.

I notice from the ActionScript docs that onRollOver doesn't provide any information about what button triggered the event. It's a shame because if it did you could use that info select the appropriate set of fields.

Dave
Didn't work. trace(i) return the correct number, but trace(this['stream'+i]); just returns undefined.
mofle
Any ideas? I have added the source file, if you want to take a look ;)
mofle
+1  A: 

Um, this may or may not help. Flash AS2 has shitty shitty scoping, and also with event driven stuff, what "i" was will be different to what "i" is. Where you have

trace(i)

although I extended it a bit to trace("i:"+i+" this.ID:"+this.ID) you will always get 5, because although i was 1-4 through the loop, the loop has finished and "i" remains 5 after you push a button (I'm a bit unsure why it's 5 and not 4...). I have found it good practice to add an ID field to movieClips in these sorts of cases.

ID is accessed with the token accessor (I think that's what it's called) as it is not a native property of the MovieClip class (I'm guessing "videobutton" is made out of a MovieClip)

for (var i:Number = 1; i<=4; i++) {
    this['videobutton'+i]["ID"]=i
    this['videobutton'+i].onRollOver = function() {
        trace("i:"+i+" this['ID']:"+this["ID"]);
        this['stream'+this["ID"]].pause(false);
        this['video'+this["ID"]].attachVideo(this['stream'+this["ID"]]);
        fadeIn(this['video'+this["ID"]]);
    }
}

I hope this works.... if not, keep posting!

Assembler
It didn't work. Here's what the trace gave me: i:5 this['ID']:1i:5 this['ID']:2i:5 this['ID']:3i:5 this['ID']:4
mofle
Any ideas? I have added the source file, if you want to take a look ;)
mofle
+1  A: 

You need to define a variable, let's say id inside each of your videobutton movieClips. These variables, unlike i, will have different values for each button. Then, you don't use this.i anymore inside your onRollOver functions, you use this.id.

Also, because the onRollOver is run on each videobutton, this inside the function points to the videobutton, not to the stage.

The new code will be:

for (var i:Number = 1; i<=4; i++) {
     this['videobutton'+i].id = i;
        this['videobutton'+i].onRollOver = function() {
        trace(this.id);
                ['stream'+this.id].pause(false);
                this.attachVideo(['stream'+this.id]);
                fadeIn(['video'+this.id]);
        };
}

It traces numbers from 1 to 5, according to what button you roll over on. It should work with the videos, too, if there's nothing else wrong with the rest of your code.

evilpenguin
It didn't work, like the others. The trace output the right number, but nothing happens. Can you download the fla and take a look?
mofle
Well, then your problem is solved and so is this question. The for loop works. You should close this question and post another one, maybe..
evilpenguin
The first other mistake i can see is that your streams are not in your videobuttons, but on stage, so you should replace attachVideo(this['stream'+this.id]) with attachVideo(['stream'+this.id])
evilpenguin
I think the problem lies with this['stream'+this.i] since it outputs undefined with trace.
mofle
this['stream'+this.i] should not be in your code. I've updated the code above, pay attention to it and replace yours with it.
evilpenguin
Writing error, I meant that i think the error is with the ['stream'+this.id]
mofle
So does it all work now?
evilpenguin
No, the flv won't show up with your code, but it does with mine. So it has something to do with the scope of "attachVideo();". Any thoughts?
mofle
updated the code. please check now. i don't have any flv to test on.
evilpenguin
['stream'+this.id] must have a path before itself, like this['stream'+this.id]. But it didn't work after I added it either.
mofle