PDA

Volledige versie bekijken : addEventListener toevoegen


Freeji
%Europe/Berlin %020 %2010, 00:29
Hallo Allemaal!
Ik laat even mijn code zien en daarna stel ik mijn vraag. Ik heb twee classes

Main class

package src{
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import src.classes.NavMenu;

public class Main extends MovieClip {

var _menuText:Array = new Array();

public function Main(){
init();
buildNavBar();
}

private function init():void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
_menuText = ["Blog","About","Contact"];//Komt straks uit een XML
}

private function buildNavBar():void {
var navBar:NavMenu = new NavMenu(_menuText);
addChild(navBar);
navBar.y=0;
/*trace(navBar.width);
trace(navBar.height);
navBar.getChildAt(1).y=20;*/
}

}

}
NavMenu class

package src.classes{

import flash.events.*
import flash.display.*;
import flash.text.*;
import src.gs.plugins.*;
import src.gs.TweenLite;

public class NavMenu extends Sprite {
//all integers
private var space:int = 10;
private var i:int = new int();
private var txtFldWidth:int = new int();
private var txtFldHeight:int = new int();
private var yValue:int = new int();
private var xValue:int = new int();

//all strings
private var _label:String = new String();
private var clipName:String = new String()
private var txtFldName:String = new String();
private var probeer:String = new String();

//all spirtes
private var clip:Sprite = new Sprite();
private var _mask:Sprite = new Sprite();

//Main function
public function NavMenu(btnNames:Array){
for each (var buttonName:String in btnNames){
var _label:Sprite = createClip(buttonName);
addChild(_label);
_label.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver)
/*trace(_label.name);*/
if (i==0) {
_label.x=0;
xValue=txtFldWidth+space;
} else {
_label.x=xValue;
xValue=xValue+txtFldWidth+space;
}

i++
}
createMask(0,0,this.width,(this.height/2));
this.mask=_mask;
i=0;
}

//aanmaken van clip met 2 texfields
private function createClip(buttonName:String):Sprite {
clip = new Sprite;
clipName = "Clip"+buttonName;
clip.name=clipName;
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
return clip;
}

//aanamken van de textfield
private function createTxtField(buttonName:String,count:int):TextFi eld{
var txtFld:TextField = new TextField();;
txtFld.y = count * -25;
txtFld.text = buttonName;
txtFld.setTextFormat(setTxtFormat(count));
txtFld.autoSize = TextFieldAutoSize.LEFT;
txtFld.selectable = false;
txtFldName = "menuBtn" + buttonName + count;
txtFld.name = txtFldName;
txtFldWidth = txtFld.width; //txtFld.width -5 om echt sluitend te krijgen
txtFldHeight = txtFld.height;
yValue = txtFld.y;
return txtFld;
}

//aanmaken van de textormat voor de textfields
private function setTxtFormat(selectColor:Number):TextFormat{
var txtFmt:TextFormat = new TextFormat();
txtFmt.font = "Cooper Std Black";
txtFmt.align = "left";
txtFmt.size = 20;
//kleur van de 2e textfield moet anders zijn
if (selectColor != 1){
txtFmt.color = 0xFF000FF;
}else{
txtFmt.color = 0x00FF00;
}
return txtFmt;
}

private function createMask(startx:int, starty:int, breedte:int, hoogte:int){
_mask.graphics.beginFill(0x000000);
_mask.graphics.drawRect(startx,starty,breedte,hoog te);
addChild(_mask);
}

private function onButtonOver(evt:MouseEvent):void{
//trace(this.name);
trace(this.clip.name);
}

}

}
Deze navigatie heeft in dit geval 3 clips. Voor elke clip wil ik een mousevent toevoegen.
Zodra ik op een van de clips klik, moet de deze zich verplaatsen zodat het een ander textveld met andere kleur tevoorschijn komt.
Nu krijg ik het niet voor elkaar om mijn event listener toe te voegen aan de afzonderlijk clips.
Op de plek waar ik het nu doe (in de NavBar Class in de functie NavMenu) werkt het half.
Als ik dan de file publish werkt de MOUSE_OVER, maar krijg ik in mijn output alleen maar de tekst "ClipContact", ongeacht de clip waar ik overheen ga met mijn muis.

Kan iemand mij misschien helpen?

Alvast bedankt.

jaspermuts
%Europe/Berlin %032 %2010, 00:46
'this' verwijst binnen je NavMenu class áltijd naar de instantie van NavMenu. In AS2 was het zo dat 'this' binnen een eventhandler zoals onButtonOver hier verwees naar datgene waar je op had geklikt. Dat is nu niet zo, je maakt in createClip steeds een nieuwe clip aan en slaat deze op in this.clip. Die var bevat dus eigenlijk altijd de laatst aangemaakte clip.
Datgene waar je op hebt geklikt kun je terughalen aan het event dat je in de functie binnenkrijgt.
de clip waar je op hebt geklikt kun je in dit geval volgens mij ophalen door

onButtonOver(evt:MouseEvent):void{

var clip:Sprite = event.target as Sprite;
}
(Zie mijn signature voor waarom ik in dit geval target zou gebruiken en niet currentTarget).
Het zou evt kunnen dat elke nieuwe clip een event listener nodig heeft, die moet je dan toevoegen in createClip().

Omdat je in createClip() steeds een nieuwe clip aanmaakt en je niet wil dat this.clip altijd alleen de nieuwste bevat, zou ik de variabele binnen deze functie declaren, ipv bij de class members. Dus ook niet gebruik maken van this.clip (bestaat dan niet meer) maar gewoon van var clip: Sprite... enz.

Freeji
%Europe/Berlin %046 %2010, 01:07
Hmmm, dit werkt niet.
onButtonOver(evt:MouseEvent (http://www.google.com/search?q=mouseevent%20inurl:http://livedocs.adobe.com/flex/3/langref/%20inurl:mouseevent.html)):void{

var clip:Sprite (http://www.google.com/search?q=sprite%20inurl:http://livedocs.adobe.com/flex/3/langref/%20inurl:sprite.html) = event.target as Sprite (http://www.google.com/search?q=sprite%20inurl:http://livedocs.adobe.com/flex/3/langref/%20inurl:sprite.html);
}
Als ik mijn eventhandler toevoeg in mijn createClip() en ik laat de function onButtonOver hetzelfde, dan krijg ik nu in mijn output "instance1". Voeg ik hem op de juiste manier toe? (zie createClip() )


package src.classes{

import flash.events.*
import flash.display.*;
import flash.text.*;
import src.gs.plugins.*;
import src.gs.TweenLite;

public class NavMenu extends Sprite {
//all integers
private var space:int = 10;
private var i:int = new int();
private var txtFldWidth:int = new int();
private var txtFldHeight:int = new int();
private var yValue:int = new int();
private var xValue:int = new int();

//all strings
private var _label:String = new String();
private var clipName:String = new String()
private var txtFldName:String = new String();
private var probeer:String = new String();

//all spirtes
private var clip:Sprite = new Sprite();
private var _mask:Sprite = new Sprite();

//Main function
public function NavMenu(btnNames:Array){
for each (var buttonName:String in btnNames){
var _label:Sprite = createClip(buttonName);
addChild(_label);
//_label.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver)
/*trace(_label.name);*/
if (i==0) {
_label.x=0;
xValue=txtFldWidth+space;
} else {
_label.x=xValue;
xValue=xValue+txtFldWidth+space;
}

i++
}
createMask(0,0,this.width,(this.height/2));
this.mask=_mask;
i=0;
}

//aanmaken van clip met 2 texfields
private function createClip(buttonName:String):Sprite {
clip = new Sprite;
clipName = "Clip"+buttonName;
clip.name=clipName;
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
addEventListener(MouseEvent.MOUSE_OVER, onButtonOver);
return clip;
}

//aanamken van de textfield
private function createTxtField(buttonName:String,count:int):TextFi eld{
var txtFld:TextField = new TextField();;
txtFld.y = count * -25;
txtFld.text = buttonName;
txtFld.setTextFormat(setTxtFormat(count));
txtFld.autoSize = TextFieldAutoSize.LEFT;
txtFld.selectable = false;
txtFldName = "menuBtn" + buttonName + count;
txtFld.name = txtFldName;
txtFldWidth = txtFld.width; //txtFld.width -5 om echt sluitend te krijgen
txtFldHeight = txtFld.height;
yValue = txtFld.y;
return txtFld;
}

//aanmaken van de textormat voor de textfields
private function setTxtFormat(selectColor:Number):TextFormat{
var txtFmt:TextFormat = new TextFormat();
txtFmt.font = "Cooper Std Black";
txtFmt.align = "left";
txtFmt.size = 20;
//kleur van de 2e textfield moet anders zijn
if (selectColor != 1){
txtFmt.color = 0xFF000FF;
}else{
txtFmt.color = 0x00FF00;
}
return txtFmt;
}

private function createMask(startx:int, starty:int, breedte:int, hoogte:int){
_mask.graphics.beginFill(0x000000);
_mask.graphics.drawRect(startx,starty,breedte,hoog te);
addChild(_mask);
}

private function onButtonOver(evt:MouseEvent):void{
//trace(currentTarget);
trace(this.name);
/*var clipp:Sprite = new Sprite();
clipp = event.target as Sprite;
var clipp:Sprite = event.target as Sprite;*/

}

}

}

jaspermuts
%Europe/Berlin %353 %2010, 08:29
Nee, nu voeg je elke keer dat je createClip() aanroept een nieuwe event listener toe aan de instantie van NavMenu. Je kunt hem beter aan clip toevoegen. Dan moet je inderdaad currentTarget gebruiken. Maar je moet wel gebruik maken van het event, niet van 'this'.
Voor de duidelijkheid: je hoeft niet élke var boven in te declareren, alleen die je buiten de functies wil gebruiken. Ook hoef je ze niet direct een waarde te geve, je geeft al een waarde in de functies, anders maak je 2x zoveel sprites als nodig bijv. En new int() slaat nergens op.. geef ze of geen waarde, of 0.

package src.classes{

import flash.events.*
import flash.display.*;
import flash.text.*;
import src.gs.plugins.*;
import src.gs.TweenLite;

public class NavMenu extends Sprite {
//all integers
private var space:int = 10;
private var txtFldWidth:int;
private var txtFldHeight:int;
private var yValue:int;
private var xValue:int;

//all strings
//private var _label:String;
//private var clipName:String;
//private var txtFldName:String;
private var probeer:String;

//all spirtes
//private var clip:Sprite;
private var _mask:Sprite;

//Main function
public function NavMenu(btnNames:Array){
var i:int = 0;
for each (var buttonName:String in btnNames){
var _label:Sprite = createClip(buttonName);
addChild(_label);
//_label.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver)
/*trace(_label.name);*/
if (i==0) {
_label.x=0;
xValue=txtFldWidth+space;
} else {
_label.x=xValue;
xValue=xValue+txtFldWidth+space;
}

i++
}
createMask(0,0,this.width,(this.height/2));
this.mask=_mask;
i=0;
}

//aanmaken van clip met 2 texfields
private function createClip(buttonName:String):Sprite {
var clip:Sprite = new Sprite; // Declareer hem binnen de functie, this.clip is geen handige variabele, omdat ie alleen de nieuwste zou opslaan (geldt ook voor clipName
clip.name = "Clip"+buttonName;
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
// voeg de event listener toe aan clip
clip.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver);
return clip;
}

//aanamken van de textfield
private function createTxtField(buttonName:String,count:int):TextFi eld{
var txtFld:TextField = new TextField();;
txtFld.y = count * -25;
txtFld.text = buttonName;
txtFld.setTextFormat(setTxtFormat(count));
txtFld.autoSize = TextFieldAutoSize.LEFT;
txtFld.selectable = false;
txtFldName = "menuBtn" + buttonName + count;
txtFld.name = txtFldName;
txtFldWidth = txtFld.width; //txtFld.width -5 om echt sluitend te krijgen
txtFldHeight = txtFld.height;
yValue = txtFld.y;
return txtFld;
}

//aanmaken van de textormat voor de textfields
private function setTxtFormat(selectColor:Number):TextFormat{
var txtFmt:TextFormat = new TextFormat();
txtFmt.font = "Cooper Std Black";
txtFmt.align = "left";
txtFmt.size = 20;
//kleur van de 2e textfield moet anders zijn
if (selectColor != 1){
txtFmt.color = 0xFF000FF;
}else{
txtFmt.color = 0x00FF00;
}
return txtFmt;
}

private function createMask(startx:int, starty:int, breedte:int, hoogte:int){
_mask.graphics.beginFill(0x000000);
_mask.graphics.drawRect(startx,starty,breedte,hoog te);
addChild(_mask);
}

private function onButtonOver(evt:MouseEvent):void{

trace(this.name); // this verwijst naar de instantie van NavMenu, niet van clip, dus hier ze je de naam vh NavMenu
var clip:Sprite = new Sprite(); // clip hoeft geen andere varnaam te hebben, hij bestaat nu alleen binnen de functie, dus het is geen conflict met die uit createClip()
clip = evt.target as Sprite; // je argument heet evt, niet event
var clip:Sprite = event.target as Sprite;
trace(clip.name);

}

}

}

Freeji
%Europe/Berlin %796 %2010, 19:06
nou krijg ik een error: 1120: Access of undefined property event.

var clip:Sprite = event.target as Sprite; Dit vind hij blijkbaar niet leuk. Deze error gaf hij eerder ook al, daarom dat ik (om te testen) de variabele naam naar clipp had veranderd. Overigens snap ik ook niet heel goed wat je met deze regel nou precies doet..? Of het werkt niet, of ik ben scheel. Ik ga er vanuit dat het het laatste is ;). Mijn file is nu dit
de tip over de variabelen declareren, neem ik mee! Bedankt voor die alvast.

package src.classes{

import flash.events.*
import flash.display.*;
import flash.text.*;
import src.gs.plugins.*;
import src.gs.TweenLite;

public class NavMenu extends Sprite {
//all integers
private var space:int = 10;
private var i:int = new int();
private var txtFldWidth:int = new int();
private var txtFldHeight:int = new int();
private var yValue:int = new int();
private var xValue:int = new int();

//all strings
private var _label:String = new String();
private var clipName:String = new String()
private var txtFldName:String = new String();
private var probeer:String = new String();

//all spirtes
private var clip:Sprite = new Sprite();
private var _mask:Sprite = new Sprite();

//Main function
public function NavMenu(btnNames:Array){
for each (var buttonName:String in btnNames){
var _label:Sprite = createClip(buttonName);
addChild(_label);
//_label.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver)
/*trace(_label.name);*/
if (i==0) {
_label.x=0;
xValue=txtFldWidth+space;
} else {
_label.x=xValue;
xValue=xValue+txtFldWidth+space;
}

i++
}
createMask(0,0,this.width,(this.height/2));
_label.mask=_mask;
i=0;
}

//aanmaken van clip met 2 texfields
private function createClip(buttonName:String):Sprite {
clip = new Sprite;
clipName = "Clip"+buttonName;
clip.name=clipName;
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
clip.addEventListener(MouseEvent.MOUSE_OVER, onButtonOver);
return clip;
}

//aanamken van de textfield
private function createTxtField(buttonName:String,count:int):TextFi eld{
var txtFld:TextField = new TextField();;
txtFld.y = count * -25;
txtFld.text = buttonName;
txtFld.setTextFormat(setTxtFormat(count));
txtFld.autoSize = TextFieldAutoSize.LEFT;
txtFld.selectable = false;
txtFldName = "menuBtn" + buttonName + count;
txtFld.name = txtFldName;
txtFldWidth = txtFld.width; //txtFld.width -5 om echt sluitend te krijgen
txtFldHeight = txtFld.height;
yValue = txtFld.y;
return txtFld;
}

//aanmaken van de textormat voor de textfields
private function setTxtFormat(selectColor:Number):TextFormat{
var txtFmt:TextFormat = new TextFormat();
txtFmt.font = "Cooper Std Black";
txtFmt.align = "left";
txtFmt.size = 20;
//kleur van de 2e textfield moet anders zijn
if (selectColor != 1){
txtFmt.color = 0xFF000FF;
}else{
txtFmt.color = 0x00FF00;
}
return txtFmt;
}

//masker maken voor over de navigatiebar
private function createMask(startx:int, starty:int, breedte:int, hoogte:int){
_mask.graphics.beginFill(0x000000);
_mask.graphics.drawRect(startx,starty,breedte,hoog te);
addChild(_mask);
}

private function onButtonOver(evt:MouseEvent):void{
var clip:Sprite = new Sprite(); // clip hoeft geen andere varnaam te hebben, hij bestaat nu alleen binnen de functie, dus het is geen conflict met die uit createClip()
clip = evt.target as Sprite; // je argument heet evt, niet event
var clip:Sprite = event.target as Sprite;
trace(clip.name);
}

}

}

reapertjuh
%Europe/Berlin %930 %2010, 22:19
verander event in evt

zoals hier

onButtonOver(evt:MouseEvent (http://www.google.com/search?q=mouseevent%20inurl:http://livedocs.adobe.com/flex/3/langref/%20inurl:mouseevent.html))

jaspermuts
%Europe/Berlin %938 %2010, 22:32
Ja, dat heb ik zelf ook in de comments gezet, maar had het op de volgende regel nog niet aangepast, dat mocht jij doen ;)

//...
clip = evt.target as Sprite; // je argument heet evt, niet event (hier had ik m aangepast)
var clip:Sprite = event.target as Sprite; // je argument heet evt, niet event (hier nog niet)
//...

Freeji
%Europe/Berlin %979 %2010, 23:30
Ja klopt jaspermuts, dat had ik inderdaad even niet goed aangepast. :) maar nog gaf hij fouten. Uiteindelijk heb ik dus gebruik moeten maken van currentTarget en niet van target. het is nu dus gelukt.
misschien toch nog even je artikeltje doorlezen? ;) als ik namelijk target gebruik, krijg ik de foutmelding

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at src.classes::NavMenu/::onButtonOver()dit is het dus geworden!

private function onButtonOver(evt:MouseEvent):void{
var clip:Sprite = evt.currentTarget as Sprite;
trace(clip.name);
}
de EventListener heb ik inderdaad in de creatClip functie gezet.


private function createClip(buttonName:String):Sprite {
clip = new Sprite;
clipName = "Clip"+buttonName;
clip.name=clipName;
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
clip.addEventListener(MouseEvent.MOUSE_OVER,onButt onOver);
return clip;
}
ik heb dus gebruik moeten maken van currentTarget en niet target.

var clip:Sprite = evt.currentTarget as Sprite

Anyways, toch bedankt voor je hulp!!

florindustries
%Europe/Berlin %995 %2010, 23:54
De klasse Sprite heeft geen .name property! Daarvoor moet je bij MovieClip zijn!

Daarom zegt 'ie dat je bij "trace(clip.name);" een onbestaande property (of method, maar dat is hier niet van toepassing) probeert te gebruiken :)

Freeji
%Europe/Berlin %021 %2010, 00:31
heej florindustries. In dat geval zou ik bij deze functie toch en error moeten krijgen?
Hier geef ik 'clip' (die een sprite is) toch een naam?? en ik krijg daar geen errors op. Of begrijp ik het niet zo heel goed?

private function createClip(buttonName:String):Sprite {
clip = new Sprite;
clipName = "Clip"+buttonName;
clip.name=clipName; <-------- hier
for(var count:int = 0;count<=1;count++){
clip.addChild(createTxtField(buttonName, count));
}
clip.addEventListener(MouseEvent.MOUSE_OVER,onButt onOver);
return clip;
}

florindustries
%Europe/Berlin %081 %2010, 01:57
Daar heb je wel een punt :P
En krijg je die error nog als je die trace in onButtonOver() even in commentaar zet?

jaspermuts
%Europe/Berlin %374 %2010, 08:59
Wat betreft die currentTarget, ook dat wist/zei ik wel in zowel di topic als mijn blog, ik had alleen de code niet op m'n tekst aangepast, dus het is begrijpelijk dat het verkeerd ging. currentTarget bevat altijd het object waar je de eventListener op hebt toegeveogd, target zou in het geval van mouse events ook een child van dat object kunnen zijn (vandaar dat in het begin van dit topic target nog wel goed was). Zie mijn blogartikel en Google evt nog op mouseChildren voor meer opheldering.

Aratramba
%Europe/Berlin %413 %2010, 09:54
@florindustries Een sprite heeft wel een name property hoor…is gewoon een displayobject :)

florindustries
%Europe/Berlin %652 %2010, 15:39
Oh ja :) Domme ik - mag niet meer zolang opblijven denk ik..
Had nochtans livedocs gecheckt, mr overerving even niet verder nagekeken.

'k Hoop dat je snel een oplossing vind :)

Freeji
%Europe/Berlin %888 %2010, 21:19
@florindusties. Die hand ik al voor jou eeste post ;) (de post boven jou eerste post)

Alles luid en duidelijk! Iedereen bedankt voor de hulp en de aanvullende info!