I have an issue that i'm running into here.. I have a set of code that is tracing that a movieclip exists on the screen, however it has not been loaded yet? What can cause this?
Printable View
I have an issue that i'm running into here.. I have a set of code that is tracing that a movieclip exists on the screen, however it has not been loaded yet? What can cause this?
You're going to have to be a lot more specific and post some code if you want answers that are more than wild guesses.
Here's a wild guess: You're tracing a variable and getting something like [object MovieClip]. That movieclip object exists, but isn't on the displayList. Trace doesn't care whether something is on the displayList.
How can I tell is something is on the displayList?
Okay,
This is the issue, I have movieclips on the timeline. In certain areas such as subnavs they are added with addChild and taken off with removeChild.. When I click "work" it will load correctly, but when I click personal then work it states that work already exists.
Here is a section
Work button code:
Code:var unimetal_homeref_mc:MovieClip;
nav_mc.workbtn_mc.addEventListener(MouseEvent.CLICK, buttonClick1);
function buttonClick1(event:MouseEvent):void {
gotoAndStop("work");
stage.invalidate();
stage.addEventListener(Event.RENDER,renderedF);
}
function renderedF(e:Event) {
unimetal_homeref_mcExists();
motionss_mcExists();
home_mcExists();
//work_mcExists();
workss_mcExists();
motion_mcExists();
workpersonalssExists();
workpersonalExists();
printss_mcExists();
}
function unimetal_homeref_mcExists():void {
if (unimetal_homeref_mc!=null) {
if (unimetal_homeref_mc.stage!=null) {
trace("YESdudemar unimetalhomeref exists");
removeChild(unimetal_homeref_mc);
} else {
trace("NO home ref does not exist");
}
}
}
////////////////////////////////////////
Here is the personal button code:
nav_mc.personalbtn_mc.addEventListener(MouseEvent.CLICK, buttonClick2);
function buttonClick2(event:MouseEvent):void {
gotoAndStop("personal");
stage.invalidate();
stage.addEventListener(Event.RENDER,renderedP);
}
function renderedP(e:Event) {
//removeChild(work_mc)
work_mcExistsp();
motionss_mcExistsp();
workss_mcExistsp();
home_mcExistsp();
//workpersonalssExistsp();
unimetal_homeref_mcExistsp();
printss_mcExistsp();
motion_mcExistsp();
//workpersonalExistsp();
}
function work_mcExistsp():void {
if (work_mc!=null) {
if (work_mc.stage!=null) {
trace("YES work_mc exists");
removeChild(work_mc);
} else {
trace("NO work_mc does not exist");
}
}
}
Do you mean that work_mcExistsp is called again when you click the work button? Yes, that would be the case. Since you clicked the personal button first, you added renderedP as a render event listener to the stage. You never removed that listener, so when you then click work, both renderedP and renderedF will be called.
Well, It has a different name and it's commented out right now..So would I remove that listener after the fact of the click, or would I remove it on another button?
You can remove the listener as soon as you don't want it to execute again. In this case, that is probably at the end of the listener itself. This little snippet should allow a listener to remove itself.
Code:function someListener(e:Event):void{
//body of listener goes here
e.currentTarget.removeEventListener(e.type, arguments.callee);
}
function buttonClick2(event:MouseEvent):void {
gotoAndStop("personal");
stage.invalidate();
stage.addEventListener(Event.RENDER,renderedP);
}
function renderedP(e:Event) {
work_mcExistsp();
motionss_mcExistsp();
home_mcExistsp();
//workpersonalssExistsp();
unimetal_homeref_mcExistsp();
printss_mcExistsp();
motion_mcExistsp();
stage.removeEventListener(Event.RENDER,renderedP);
}
That's what I did and it seemed to work perfect so far. Thanks!
Or that, yeah.
okay, one weird thing here...Everything works correctly but I found one way to break it:) muahhaahha. So, if i go from work>personal>work>personal the last personal page won't load..The error is a display child must be a blabhlahlb, but it works those other times? Strange huh? Also, vice versa from personal to work breaks it as well. By breaking it mean the page just won't show up.
The "blabhlahlb" is probably "child of the caller", which means that either the object isn't on the displaylist at all at that point, or it is a child of something else. Since you haven't posted the code where you add these things to the displaylist, I can't really help with that.
Yes. That's what it is:) I'll post up the code for both of those buttons.
Forgive me, I know it's a chuck of code. I just want to make sure all the bases are covered.
Here is the sequence:Code:
var unimetal_homeref_mc:MovieClip;
nav_mc.workbtn_mc.addEventListener(MouseEvent.CLICK, buttonClick1);
function buttonClick1(event:MouseEvent):void {
gotoAndStop("work");
stage.invalidate();
stage.addEventListener(Event.RENDER,renderedF);
}
function renderedF(e:Event) {
unimetal_homeref_mcExists();
motionss_mcExists();
home_mcExists();
//work_mcExists();
//workss_mcExists();
motion_mcExists();
workpersonalssExists();
workpersonalExists();
printss_mcExists();
stage.removeEventListener(Event.RENDER,renderedF);
}
function unimetal_homeref_mcExists():void {
if (unimetal_homeref_mc!=null) {
if (unimetal_homeref_mc.stage!=null) {
trace("YESdudemar unimetalhomeref exists");
removeChild(unimetal_homeref_mc);
} else {
trace("NO home ref does not exist");
}
}
}
function motionss_mcExists():void {
if (motionss_mc!=null) {
if (motionss_mc.stage!=null) {
trace("YESdudemar motion ss does exist");
removeChild(motionss_mc);
} else {
trace("NO motionSS does not exist");
}
}
}
function home_mcExists():void {
if (home_mc!=null) {
if (home_mc.stage!=null) {
trace("YESdudemar home exists");
removeChild(home_mc);
} else {
trace("NO HOme does not exist");
}
}
}
function workss_mcExists():void {
if (workss_mc!=null) {
if (workss_mc.stage!=null) {
trace("YESdudemar workss exists");
removeChild(workss_mc);
} else {
trace("NO workss does not exist");
}
}
}
function motion_mcExists():void {
if (motion_mc!=null) {
if (motion_mc.stage!=null) {
trace("YES motion exists");
removeChild(motion_mc);
} else {
trace("NO motion_mc does not exist");
}
}
}
function workpersonalssExists():void {
if (workpersonalss_mc!=null) {
if (workpersonalss_mc.stage!=null) {
trace("YES workpersonallsss exists");
removeChild(workpersonalss_mc);
} else {
trace("NO work personalss does not exist");
}
}
}
function workpersonalExists():void {
if (workpersonal_mc!=null) {
if (workpersonal_mc.stage!=null) {
trace("YES work personal does exist");
removeChild(workpersonal_mc);
} else {
trace("NO work personal does not exist");
}
}
}
function printss_mcExists():void {
if (printss_mc!=null) {
if (printss_mc.stage!=null) {
trace("YESdudemar printss does exist");
removeChild(printss_mc);
} else {
trace("NO PRINTss_MC does not exist");
}
}
}
//////////////////////////////////
nav_mc.personalbtn_mc.addEventListener(MouseEvent.CLICK, buttonClick2);
function buttonClick2(event:MouseEvent):void {
gotoAndStop("personal");
stage.invalidate();
stage.addEventListener(Event.RENDER,renderedP);
}
function renderedP(e:Event) {
work_mcExistsp();
motionss_mcExistsp();
workss_mcExistsp();
home_mcExistsp();
//workpersonalssExistsp();
unimetal_homeref_mcExistsp();
printss_mcExistsp();
motion_mcExistsp();
stage.removeEventListener(Event.RENDER,renderedP);
}
function motionss_mcExistsp():void {
if (motionss_mc!=null) {
if (motionss_mc.stage!=null) {
trace("YESdudemar motion ss does exist");
removeChild(motionss_mc);
} else {
trace("NO motion ss does not exist");
}
}
}
function motion_mcExistsp():void {
if (motion_mc!=null) {
if (motion_mc.stage!=null) {
trace("YES motion exists");
removeChild(motion_mc);
} else {
trace("NO motion_mc does not exist");
}
}
}
function printss_mcExistsp():void {
if (printss_mc!=null) {
if (printss_mc.stage!=null) {
trace("YESdudemar printss does exist");
removeChild(printss_mc);
} else {
trace("NO PRINTss_MC does not exist");
}
}
}
function unimetal_homeref_mcExistsp():void {
if (unimetal_homeref_mc!=null) {
if (unimetal_homeref_mc.stage!=null) {
trace("YESdudemar unimetal does exist");
removeChild(unimetal_homeref_mc);
} else {
trace("NO home ref does not exist");
}
}
}
/*
function workpersonalssExistsp():void {
if (workpersonalss_mc!=null) {
if (workpersonalss_mc.stage!=null) {
trace("YES work personalss does exist");
removeChild(workpersonalss_mc);
} else {
trace("NO work personalss does not exist");
}
}
}
*/
function workss_mcExistsp():void {
if (workss_mc!=null) {
if (workss_mc.stage!=null) {
trace("YES workss does exist");
removeChild(workss_mc);
} else {
trace("NO workss does not exist");
}
}
}
function work_mcExistsp():void {
if (work_mc!=null) {
if (work_mc.stage!=null) {
trace("YES work_mc exists");
removeChild(work_mc);
} else {
trace("NO work_mc does not exist");
}
}
}
function home_mcExistsp():void {
if (home_mc!=null) {
if (home_mc.stage!=null) {
trace("YESdudemar home-mc does exist");
removeChild(home_mc);
} else {
trace("NO home_mc does not exist");
}
}
}
Work clicked = no error, page loads
Personal Clicked = no error, page loads
Work Clicked = Error, page still loads
Error:Personal Clicked = No error, Page does not load, Traces "YES work personal does exist"Quote:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at SILVERCOLLECTIVEv13cs4_fla::MainTimeline/workpersonalExists()[SILVERCOLLECTIVEv13cs4_fla.MainTimeline::frame1:35 3]
at SILVERCOLLECTIVEv13cs4_fla::MainTimeline/renderedF()[SILVERCOLLECTIVEv13cs4_fla.MainTimeline::frame1:27 4]
That code still doesn't have the addChild calls. I suspect that you are adding it to a different parent at some point, probably the stage.
True, I'll post that up shortly. If i never access that how could it create an error? Would the error be removing the child?
That error happens when you try to remove a child from something it is not a child of. That could be because you've already removed it. Or it could be because it was added as a child of something else, which would implicitly remove it. Or it could be because it was never added to that object in the first place.
Alright, I get it.. This is what is happening here. The main pages are based on the timeline, then once you get into say you go to work_mc then you load an image in there I am using an addChild event to trigger workss_mc to be loaded. However in workss_mc there is an option to go back. When you do go back, this removes workss_mc and adds work_mc. So this is my question, how can I pull this off instead of how i currently have it since it's obviously not working correctly.
So if I remove the workpersonalExists from the work button and if I remove work_mcExistsp function it will work correctly navigating but now it won't remove that movieclip once it's loaded from pressing the back button..
If I understand correctly (and there's a good chance I don't since this is so convoluted), you want a single thing on the screen at a time.
If that's the case, then just set a variable to point to the currently showing content. When showing new content, if that variable is non-null, remove the existing content, add the new content, then set the variable to the new content.
Yes, that is correct. A single thing on the screen at a time. If you want to take a look
go to:
http://iankemp.com/silver/SILVERCOLLECTIVEv13cs4.swf
Feel free to give me some feedback too.. So, go into work, then click something and click back and just mess around in there. You'll see. I'll take a shot at what you are trying to say and show you what I come up with.
Alright i've been storming my brain about this and I can't figure it out..
So this is what has to happen. Work_mc has to be removed when you click personal_btn under only one occurrence. When it is loaded from workss_mc. When it is loaded from workss_mc it is done with addChild.
So this is the navigation in a whole.
Button
Work -> work_mc(selection of work)(on timeline) -> workss_mc (this contains all work) added as a child
Personal -> personal_mc(selection of work)(on timeline) -> persoanlss_mc (this contains all personal work) added as a child
So the goal is here, is once you are in personalss_mc or workss_mc you need to be able to go back to personal_mc or work_mc to look at the selection of work here, so by doing this I am using addChild & removeChild. This is where the problem lies, if a user does this then decides to swap pages then the page overlaps work_mc or personal_mc.
Technically, I guess I could get rid of workss_mc and personalss_mc and put them all into work_mc and personal_mc. Then I would run into all sorts of other things as well b/c once you are in workss_mc or personalss_mc there is also a prev and next button which will go to the next frame if the user decides to navigate that way. hmm
The hacky way to get around the error would be to simply test that the child is contained before trying to remove it.
Code:if (contains(child)){
removeChild(child);
}
I tried that right here... That's basically what I have.. But i added the contains when you click the navigation button.
Here is the code:
Code:
function workExistss():void {
if (work_mc!=null && contains(work_mc)) {
if (work_mc.stage!=null) {
trace("YES work exists");
removeChild(work_mc);
} else {
trace("NO work does not exist");
}
}
}
ah. alright. fixed it.. One more question for ya if you don't mind..
O In my work section i have a subnav which goes to motion, print, web, and all. I believe this is a scope issue but I just want to see what you think.
Once you load, let's say motion, that will goto the root frame label "motion".
Following that you will click a link there which will take you to a certain frame label in motionss_mc. Inside of motionss_mc I am dispatching an event to the root timeline to close motionss and open back up motion_mc if you so choose
That would be the backmotionss_Clicked2 function.Code:motion_mc.twentythreemographthmb_mc.addEventListener(MouseEvent.CLICK, motionHandler8);
motion_mc.twentythreemographthmb_mc.buttonMode = true;
function motionHandler8(event:MouseEvent):void {
if (!motionss_mc) {
motionss_mc = new mc_motionss();
motionss_mc.addEventListener("closemotionButtonClick2", backmotionssClicked2);
motionss_mc.x = 225;
motionss_mc.y = 200;
}
motionss_mc.gotoAndStop("twentythree")
addChild(motionss_mc);
removeChild(motion_mc);
}
function backmotionssClicked2(e:Event):void {
trace("clickedtrue");
if (!motion_mc) {
motion_mc = new mc_motion();
motion_mc.x = 225;
motion_mc.y = 200;
}
addChild(motion_mc);
removeChild(motionss_mc);
}
So in the subnav and continue to a link, close that link with the backmotionss_Clicked2 function then navigate to another section of the subnav...When I do this in that order, motion_mc stays at that section that is currently loaded..
So I am trying to clear it with this:
Code:
var motion_mc = motion_mc
workcatagorydropdown_mc.catagoryinteractive_mc.addEventListener(MouseEvent.CLICK, interactiveHandler);
function interactiveHandler(event:MouseEvent):void {
newRoot.gotoAndStop("web");
stage.invalidate();
stage.addEventListener(Event.RENDER, renderedI);
}
function renderedI(e:Event) {
motion_mcExistsI();
stage.removeEventListener(Event.RENDER,renderedI);
}
function motion_mcExistsI():void {
if (motion_mc!=null) {
if (motion_mc.stage!=null) {
trace("motion does exist");
removeChild(motion_mc);
} else {
trace("no motion does not exist");
}
}
}
Please note that the following code is inside of the subnav which is located a few pages deep. Notice the usage of root.
bump
I'm sorry, I didn't follow that. I'm having a very hard time understanding the structure of your movie since there seem to be a lot of layers and similarly named objects. Could you perhaps draw a diagram of your intended design?
I did notice that you are adding listeners to content in motion_mc before it necessarily exists. That would throw errors if it does not exist. And if motion_mc when those handlers is added is a different instance than later, those handlers won't be triggered because they're not on the new dispatching instance.
Does nothing. Inside a function, it would establish a new function-scoped variable by that name so that if you assigned something to that variable later in the function it would not affect the value of motion_mc outside that function. I'm not sure if that's what you were going for.Code:var motion_mc = motion_mc;
I don't see any code following "the following code", and if you meant the preceding code, it does not use root, so I don't know what you wanted me to notice regarding the usage of root.
Yeah, I can. Did you get a chance to look at the swf?
also, I would be willing to let you look at the .fla if you want? By following i meant previous:) Actually I did set up a variable for newRoot = root, which is not shown.. and
function interactiveHandler(event:MouseEvent):void {
newRoot.gotoAndStop("web");
That is where I am using the root.
I did look at the swf, it is clearly not removing things as you'd hope for, but it's hard to draw conclusions from that. I'm not getting error messages, but I might not have the debug player installed here at work.
Unfortunately, I cannot open fla files.
Using newRoot.gotoAndStop like that is fine. It is essentially no different than just using root.gotoAndStop, with the exception that newRoot would retain a reference even after that instance is removed from the displayList. But since that function is a click handler, that should not be an issue.
Alright, I'm working on a diagram to help you understand this.. Yeah, there are no error messages, it's just not removing the movieclip when it should.
okay, Check this out. Let me know if this helps.
Please note. Motion_mc is on the root timeline
The problem happens after I press the back button then try to load another movieclip from the subnav.
All this code is in the root context right?
I think instead of trying to keep track of what could possibly be showing and trying to remove that specific thing when you put something new up, you should have a variable to keep track of the currently showing modal content and a function to replace it.
Now instead of calling addChild and removeChild, simply call showModalContent to get something on the display in that mutually exclusive role.Code:var currentlyShowing:MovieClip = null;
function showModalContent(clip:MovieClip):void{
if (currentlyShowing != null){
removeChild(currentlyShowing);
}
currentlyShowing = clip;
addChild(currentlyShowing);
}
I'm really not certain what all that stuff is with the rendered events. It looks like all you're trying to do is remove motion_mc if it's on the display. You could make a removeModalContent function to simply clear any modal content that's up there.
You should not have to have different methods to remove content for each particular navigational function.Code:function removeModalContent():void{
if (currentlyShowing != null){
removeChild(currentlyShowing);
currentlyShowing = null;
}
}
I would put the showModalContent in the button listener?
Not all of the code is on the root. The only code that is on the root timeline that you are seeing is the motion_mc code.
Any time you have removeChild(something); addChild(somethingelse);, just use showModalContent(somethingelse);
If the subnav code is not in the root context, then motion_mc is undefined there. I would expect a compilation error when you declare and initialize the local motion_mc variable. Anyway, since you are changing the root motion_mc to new instances all the time, you don't want to compare it to a particular motion_mc instance anyway. Instead of all that somethingExists crap, just call root.removeModalContent(). That was probably the source of your issue. motion_mc in that context was not the same thing as motion_mc in the root.
You are saying that I should be putting the removeModalContent(); on the root? Sorry, I'm not familiar with showModalContent and RemoveModalContent
I just made them up, I don't expect you would be familiar with them.
Yeah, define the functions showModalContent and removeModalContent on the root (assuming that is where you want your modal content to be added to). Then call those root functions from anywhere.
The idea behind those functions is that you don't have to keep track of every permutation that the user could have done. You know that there is at most one thing to remove when you are putting up something else. And because you kept track of what that one thing was last time you showed something, you can easily remove it without caring about what it is.
Since the instance of motion_mc is changing all the time, that wouldn't be a problem?
I should put that inside of motion_mc no?
Since each time you show motion_mc, you should show it through showModalContent, then no it does not matter that you use different instances. The latest (and currently showing) will always be in the currentlyShowing variable that showModalContent and removeModalContent reference.
Alright, Check it out. Let me know if i'm doing this correctly b/c I'm obviously not...
Inside of the subnav I have this:
AND on the root timeline at the motion framelabel I have this:Code:workcatagorydropdown_mc.catagoryinteractive_mc.addEventListener(MouseEvent.CLICK, interactiveHandler);
function interactiveHandler(event:MouseEvent):void {
newRoot.removeModalContent();
newRoot.gotoAndStop("web");
}
Code:var currentlyShowing:MovieClip = null;
function showModalContent(clip:MovieClip):void{
if (currentlyShowing != null){
removeChild(currentlyShowing);
}
currentlyShowing = clip;
addChild(currentlyShowing);
}
function removeModalContent():void{
if (currentlyShowing != null){
removeChild(currentlyShowing);
currentlyShowing = null;
}
}
Yeah, that's what I meant. What's the problem?