views:

543

answers:

2

I load a swf via the Loader() class. As the swf is loaded I loop through all the children of root and remove any TextField with removeChild(). This works initially - the TextField is removed. But as a tween in the loaded swf finishes and loops, the removed TextField somehow reappears. The TextField is Dynamic text. If I remove some StaticText, this stays removed. What is going on here?

loopChildren(root);
function loopChildren(dispObj:*):void {
    for (var i:int = 0; i< dispObj.numChildren; i++) {
        var obj:DisplayObject = dispObj.getChildAt(i);
        if (obj is DisplayObjectContainer) {
            loopChildren(obj);
        }
        else {
            if (obj is TextField) {
                obj.parent.removeChild(obj);
                i--;
            }
        }
    } 
}

If I call loopChildren with a timer (5 sec intervall) and trace(obj.name) for all children, I notice that the obj.name changes. The TextField is called instance11, instance32, instance54 and so on. It seems that a new instance is created and added continuously?

EDIT: If I transfer the code directly to the swf and run it without using the wrapper it works as expected. I must be missing something that happens when its loaded through another movie?

EDIT2: I should say that the TextField I'm trying to remove is in a separate layer on the same time line as the tween. If I put the tween in its own timeline, it seems to work as expected. But can't dynamic text and tween live together?

+1  A: 

It sounds like your text field is defined on the stage (i.e. in the FLA, not instantiated by script), and the layer it's on probably has a keyframe that is played through at some point in your tween.

If that's correct, then what you're running into is a fairly low-level limitation of Flash regarding the competing natures of the timeline and the script environment. When you play through a tween, every timeline keyframe encodes some information for Flash about what sorts of object should be on the stage at that point, and where they should be, etc.

But when you also start referencing those same object with script, in general Flash has to guess whether you want the script or the information in the timeline to take precedence. In this case, probably what's happening is that after you remove the text field with script, one of the frames your tween plays through references the same field, and Flash doesn't know whether the removal was supposed to be permanent, or whether to honor the keyframe and recreate the field.

Thus, the short answer (too late!) to your question is, in general you should try to handle your stage elements with timeline tweens, or script, but not both. This is why your solution in edit #2 worked; because by moving the tween onto its own timeline, (I'm guessing) you no longer played across keyframes that encoded information about the text field in question. Another solution would probably be to remove the offending text field via the timeline (by playing to a keyframe where that text field no longer exists). Or, of course you could also control your textfield solely by script, creating it and destroying it, so it's never part of the timeline at all.

fenomas
Good job, you're spot on in all your assumptions! As you've probably already understood, I'm trying to manipulate elements in swf-movies by loading the movie in a parent movie. Problem is, I'd like the changes I make to the structure and text etc. to be permanent. Do you know of any way to accomplish this? I guess one way would be to somehow tie my controlling actionscript to the keyframes of the loaded movie and making sure it executes when the movie loops, making the changes again and again.
dagge
I think I'll ask another question regarding this.
dagge
A: 

Why not just set the text field to empty?

loopChildren(root);

function loopChildren(dispObj:DisplayObjectContainer):void 
{
    for each(var i:int = 0; i < dispObj.numChildren; i++) 
    {
        var obj:DisplayObject = dispObj.getChildAt(i);
        if (obj is DisplayObjectContainer) 
        {
            loopChildren(obj);
        }
        else if (obj is TextField) 
        {
            TextField(obj).text = "";
        }
    } 
}
James Fassett