Removing Things Using Code

by kirupa  |  15 April 2011

  Have questions? Discuss this Flash / ActionScript tutorial with others on the forums.

In an earlier tutorial, you learned how to write some code and dynamically add content either to your stage or another movie clip. Adding items is only one part of the picture. At some point, you may want to remove them as well. In this tutorial, you will learn how to write some code to remove visual elements such as Movie Clips and Sprites.

Note
Technically, you will be learning how to remove DisplayObjects, but almost everybody refers to them as MovieClips, Sprites, or a host of other things that derive from it instead.

The following is an example that shows movie clips being removed when you click on the minus button:

[ in hindsight, this example is probably annoying ]

Keep clicking on the minus button to see more movie clips being removed. Eventually, you will run out of movie clips to remove. If you feel sad at the thought of that, don't worry. Just refresh the page and all of the movie clips will find their way back.

Looking Under the Hood
When you are adding things to display, have you ever wondered how these things get stored internally? Well, understanding a bit more about how that works will help you greatly make sense of what actually happens when you add or remove an element.

Internally, you have a list that deals with everything related to displaying the things you see. This list is affectionately known as the display list:

the display list 

Every visual element (aka things derived from DisplayObject) you have is represented in this list. The position of items inside this list is based on z-order. While you probably know this from non-Flash experience, the higher the number, the higher in the stack your object object will appear.

The previous diagram simplfied things greatly. The display list is by no means flat. Each entry in the display list could be a container which, in turn, contains children of its own:

nested tree

In this diagram, squareBar is a container that has other elements inside it. The technical term for container is anything that derives from DisplayObjectContainer such as a Sprite or MovieClip. Within each DisplayObjectContainer, you have your own list of children whose position in the list maps to z-order as well.

Ok, so that's all for the dissection of what goes under the hood. Keep some of this under your hat as we start to look at how to remove elements.

Removing Items
The primary function you use to remove a DisplayObject such as a MovieClip is removeChild.

There are two things to specify when using removeChild. First, you call this function on the container the element you wish to remove resides in. Second, you pass the element you wish to remove as the argument to removeChild.

Basically, it will look something like this:

container.removeChild(elementToRemove);

In most cases, the container is commonly your stage or another MovieClip instance such as squareBar from the earlier example. Your elementToRemove is anything that is based off of a DisplayObject such as a Sprite, MovieClip, etc. that lives inside the container you have your eyes on.

If you wish to remove an element at a particular z-index from your container's list of children, you can do that by passing the z-index value to the removeChildAt function:

container.removeChildAt(3);

In this example, you are removing the element at the z-index of 3. All elements inside this container who have a higher z-index than the one you just removed will have their z-indexes appropriately reduced by 1. You will never have gaps in your z-order.

You Can't Remove what Doesn't Exist
One thing you need to ensure is that the element you remove is something that actually exists in your container. The way you can check for that is to use the contains function:

if (movieContainer.contains(circle))
{
movieContainer.removeChild(circle);
}

In our example, you are checking to see if your circle movie clip exists inside movieContainer. If it exists, you go ahead and call removeChild on it. Poof - the circle goes away. If that movie clip does not exist, then you don't have to worry about removing it because it never existed.

If you are using removeChildAt, you need to ensure that the index value (which is your z-index value really) you are providing doesn't go higher than the highest element in your list. There is a direct correlation between the number of items in your list and the highest index value allowed, so you can just check for the number of items in your container before attempting to remove it by index:

if (targetMovieClip.numChildren > elementIndex)
{
targetMovieClip.removeChildAt(elementIndex);
}

The way you check for the number of items is by using the numChildren property on your container object to return the number of children it is currently hosting. If the number of children inside the container is greater than the index number (which is zero based) you are trying to remove, then you can be assured that the element at the index you are trying to remove can indeed be removed!

Deleting All Children
If you want to remove all children from a container, the easiest way is to go through each child in the container and remove it individually:

var i:Number = targetMovieClip.numChildren;
while (i--)
{
targetMovieClip.removeChildAt(i);
}

Notice that I am removing the elements in reverse order from your container. The reason has to do with a subtle detail I snuck in when describing the removeChildAt function:

All elements inside this container who have a higher z-index than the one you just removed will have their z-indexes appropriately reduced by 1. You will never have gaps in your z-order.

When you remove an element from the bottom of your stack, Flash goes through the stack and updates all of the z-index values for the remaining elements to account for the removed element.

By removing the element at the top, Flash doesn't have to do any re-indexing because there are no elements that would be affected when the element gets removed. This is a performance optimization, but if you do not have that many children or don't want to deal with the slight complexity in your code, you can remove elements the more traditional way instead:

while (targetMovieClip.numChildren > 0)
{
targetMovieClip.removeChildAt(0);
}

In this approach, you are just removing the bottom most element until you have no more elements to remove.

Conclusion
Well, that's all there is to removing elements so that you no longer see them. When an element is removed, nobody quite knows what happens to it. Some say it lives in a better place. Some feel that it disappears into nothingness.

The truth is a little bit in-between. If a removed element has no references to it, such as through an array or something, it will be garbage collected automatically once removed. If a reference exists somewhere, your element will not be visible, but it may still live in memory until any references to it are fully removed.

If you want to see my final source code for the example where you remove a hundred circles by clicking a hundred times, download it from below:

Download Final Source Files

Extract the files and open the removingMC.fla and Main.as to run and examine the example for yourself.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.