Is _root Evil?

ActionScript 2.0

People tend to feel strongly about their personal preferences.  Some folks love the global _root property, while others absolutely hate it.  Not everyone is vocal, of course, so any passion expressed in online discussion of the empirical merits of _root may be skewed.  Hard to say.

In this article, I hope to give you enough information to make your own informed decision.  Then you can get as passionate as you like. ;)  

What is _root?

_root is a global property, which means it can be accessed from anywhere in your code.  From the point of view of any timeline, from any on() or onClipEvent() event handler attached to any object, or scoped to any function, _root always refers to the same thing.  And what is that?  Succinctly, _root refers to what is generally called “the main timeline.”

Where the confusion starts

Now, since I said “always” and “the same thing,” allow me to hastily add that caveats do apply:  the definition of “main timeline” is somewhat malleable, and I suspect it is this potential for confusion that frustrates people who prefer not to use _root.

Your SWF doing the loading

To be more specific, _root actually refers to the main timeline of the current document level.  Chances may very well be that your current document level is _level0, the default.  Flash does, however, support multiple levels.  This is something akin to opening more than one document at the same time in your favorite word processor.  If you use the global loadMovieNum() function to load external SWFs at runtime, then _root will point to whatever level is currently active.

If you don’t load external movie clips, or if you load them into movie clip containers via loadMovie(), MovieClip.loadMovie(), or the MovieClipLoader class, then _root will always point to _level0.

As it turns out, we’re actually still not in the clear, but I want to pause for a moment to explain when a person might use _root.  Objects in ActionScript are hierarchical.  You might, for example, have three movie clips nested inside each other where the innermost movie clip contains a button.  This button may be expected to execute a function defined in a frame of the main timeline.

From an objective point of view, the button’s position is here …

_level0.mcA.mcB.mcC.button;

From the button’s point of view, the function it intends to trigger is positioned here …

this._parent._parent._parent.function();

… which can be difficult to scan visually.  Now, using _root in the following context provides a shortcut to the main timeline …

_root.function();

Less to type, and that’s essentially the reason people who use _root do.

Now, obviously, if the desired function exists in _level0, but the nested movie clips exist in _level1 (and if _level1 is the currently active level), then _root would refer to _level1’s main timeline and the function would not be found.  You would have to explicitly refer to _level0.function() from the button’s point of view.  Depending on setup of your main and loaded SWFs, this may not be feasible.

Your SWF being loaded by another

Even if you don’t load external SWFs into levels, you may see one additional case in which _root seems to change meaning again.  Your SWF might actually get loaded by another SWF.  In such a case, the above information still applies, but from the opposite angle.  The true _root is still the main timeline of the current document level, but only the outermost SWF’s main timeline counts.  This makes perfect sense, of course:  any SWF loaded into another loses the privilege of calling its own main timeline the main timeline.  If a loaded SWF contains references to _root in its own code, those references will no longer resolve to the main timeline of that SWF, but to the main timeline of its topmost parent, however long the hierarchy stretches.

Summary

Seemingly, _root changes meaning every time you turn around.  But remember, it just ain’t so.  The global _root property refers to the same location every time.

_root always refers to:

  • the main timeline
  • of the current document level
  • of the outermost SWF

Except … except if the MovieClip._lockroot property of the loaded SWF is set to true.  Introduced in Flash MX 2004 (Flash Player 7), the MovieClip._lockroot property allows references to _root in a loaded SWF to continue resolving to its own timeline.  This feature was presumably introduced to allow developers to load older, _root-reference–heavy movies without breaking.

Conclusion

Admittedly, _root takes a bit of thinking to “get,” but once it makes sense, it makes sense.  If the buck stops with you — and it often doesn’t, in team settings — you might just decide that _root is a legitimate shortcut for referring to the common starting point of all your movie’s objects.  You might purposefully write a _root reference in the full knowledge that it cannot resolve to the desired timeline in isolation — that this SWF must load another, or be loaded by another, in order for _root to point where you intend.  I compare this to using root-relative versus document-relative hyperlinks in HTML.

On the other hand, you may find the above too much to keep track of, to the point that the “shortcut” of using _root costs more in terms of thinking than it saves in terms of typing.  One of the founding principles of object-oriented design, after all, is to reduce (ultimately, to circumvent) dependence on outside factors, such as the varying location to which _root may resolve.

Whatever you decide, make sure you know the reasons for your choice, then stick with what works best for you.

19 Responses to “Is _root Evil?”

  1. Tiemen Says:

    Right, so if you have a loader.swf which uses the MovieClipLoader (heh..) to load the main swf into movieclip “stage_container” the objective path to the main swf’s former root becomes _root.stage_container? Any functions in the main swf calling a function in it’s root will refer to the loader’s root instead and won’t find their targets, right?

    But it you simply loaded the movie into level1 you would get the same result, except for not being able to manipulate properties like _x and _y?

    Hm. I’ve been fiddling around a bit with the above, but those levels seem to be more difficult to access. I don’t seem to be able to load a movieclip into a level using the MovieClipLoader. Using LoadMovieNum works though.

    While depth in a movieclip is effectively described by visualising a stack of transparent slides, or just the general “layers” principle used in the timeline/stage enviroment and in Photoshop, levels in flash add a lateral axis to that principle? The having open different documents principle you described? And internally everything in level1 has a higher depth than level0, but no relative path exists between levels.

    Just an example for me to understand:

    1. I have a loader swf that loads a main swf into a container with depth 1. If I have a function that says _root.createEmptyMovieClip("example", 0) content replacing that movieclip will be placed on behind the main.swf
    2. If I load the main swf in _level1 this function will create a movieclip thats on top of main swf, no matter what, unless I specify _level1.

    ?

  2. Tiemen Says:

    hm. that “no matter what” : not regarding the depths used in this main.swf, in this example assume they are negative.

  3. David Stiller Says:

    Tiemen,

    Right, so if you have a loader.swf which uses the MovieClipLoader (heh..) to load the main swf into movieclip “stage_container” the objective path to the main swf’s former root becomes _root.stage_container?

    Yes.

    Any functions in the main swf calling a function in it’s root will refer to the loader’s root instead and won’t find their targets, right?

    Exactly. That’s why many people consider _root references “evil,” though that seems silly to me. If you know your tools, then won’t hurt you. In fact, they even do your bidding. ;) I often use _root to reference the mouse position, and it makes good sense in that context.

    I don’t seem to be able to load a movieclip into a level using the MovieClipLoader.

    Hmm. Works fine for me. Just specify a number in the second parameter, rather than a movie clip instance.

    var mcl:MovieClipLoader = new MovieClipLoader();
    mcl.loadClip("a.jpg", 3);

    I suppose it’s fair to say layers add a “lateral” axis, but only metaphorically: they’re certainly not shifted visually in any way. Two images opened at the same time in Photoshop is a good analogy.

    I believe you answered your own last two questions correctly, though it’s easy enough to test. ;)

  4. Tiemen Says:

    Mmmh it’s great stuff, this blog of yours!
    While writing such a summary is great for me personally, I thought reciting it from another perspective might be of use for other readers… I’m just ‘commenting’ this time, not desperately demanding your help like I did at the Event Listeners entry ;-)

    But great feedback!

  5. rushed Says:

    Aaaahh… so does “_root” always equal “_level0″ except when “_lockroot” is enabled??? Just so its clear.

  6. David Stiller Says:

    rushed,

    If content is loaded into level 2, then references to _root point to _level2 in any code references of that content. So _root does not always point to _level0. The MovieClip._lockroot property allows loaded content to refer to its own main timeline rather than the main timeline of the relevant level of the parent-most movie.

  7. Dario Says:

    Hi.
    Maybe you can help…
    - Flash MX (AS 2) -
    I have a main movie with a menu that I use to load external SWF files in a
    “target clip”.
    In the external files I often use “_level0″ sintax, but when these files are
    loaded inside the main movie I have to use the name of the “target clip”
    insted of “_level0″; and if I want to test these files outside the main
    movie I have to rewrite again!
    It’s terrible!!
    How can I escape from that?

  8. Dario Says:

    sorry!
    I meant AS1. (or not?) mmh….

  9. David Stiller Says:

    Dario,

    You shouldn’t have to rewrite anything, actually. I’m not sure what your references to _level0 are used for in the external files, but as discussed in the article, those references change depending on whether the files stand alone or are loaded into another SWF. If the ActionScript in your external files must reference _root or _level0, you could set up an if statement that checks to see if the current file (the external file) has a parent. If it does, that means it’s been loaded, and you can make your references one way. If it doesn’t, that means it stands alone, and you can use other paths.

    e.g.
    if (this._parent) { ... }

  10. Dario Says:

    Hey, that’s a help! Thank you!! ;)
    My script is inside a clip, inside another clip, inside one more clip, maybe inside…..
    Can you suggest me a line of code to find out (from this deep clip) if my “stan-alone-root” is (or not) the “real-root”?
    (I’m not really an AS ace!)

  11. Dario Says:

    (Maybe) I’ve found a way…
    I set a variable in the main timeline of my loaded SWF:

    effroot = 1;

    …and then I write this (everywhere) when I want to test where that SWF is:

    if (_root.effroot == 1) {
    trace("stand alone");
    } else {
    trace("inside");
    }

    It should work.

  12. David Stiller Says:

    Dario,

    Flash often allows dozens of solving the same problem. Your approach may just do it. You could also use …

    if (this._parent._parent._parent) { ... }

    … nested as often as makes sense.

  13. mindaugas Says:

    this._lockroot = true;
    on first frame of external swf, for me it’s working:)

  14. David Stiller Says:

    mindaugas,

    Rockin’! :)

  15. Claudiu Says:

    I have main moviclip.Inside this movieclip I have 2 layers. On the 1st keyframe of layer1 I have _root to moviclip to load
    [ _root.section != “a.swf”; {
    _root.section = “a.swf”;
    _root.transition.gotoAndPlay(”closing”); ]

    thing is this is not leading me to the a.swf. I need to know the road to that a.swf.

    P.S. If I have the 2 layers on scene1 the path, shown above, works

  16. David Stiller Says:

    Claudiu,

    It may help you to understand that timeline layers are merely a convenience during authoring. In the published SWF, timeline layers are translated into a complex series of depths that correspond to layers, but aren’t actually the same thing.

    Your ActionScript, as shown, leaves me a bit confused. I’m not sure what your three lines mean (I don’t see any lines that load an external SWF). What approach have you used to load your content — MovieClipLoader, for example? If so, you will have specified a target (a movie clip container) into which your external SWF should load. That target will be the path you need.

  17. sydney Says:

    Hey, I just wanted to say thank you.
    this bit:
    this._parent._parent._parent.function();
    … which can be difficult to scan visually. Now, using _root in the following
    context provides a shortcut to the main timeline …
    _root.function();
    cleared up about 2 weeks of class that I didn’t understand! your writting is fantastic.
    Thank You!!!!

  18. David Stiller Says:

    sydney,

    Glad to hear it! :) Although I’m happy this blog entry clarified matters for you, I can’t stress enough (not just to you, but anyone) that you shouldn’t rely on _root as a crutch. Understand it, use it when appropriate or convenient, but be aware of its limitations.

  19. cusoftcl Says:

    Fear and Faith A Mormon’s Ultimate Doorbell link [url=http://41.x004.in/7.html]link[/url] link [url=http://09.x004.in/22.html]link[/url] link [url=http://07.x004.in/28.html]link[/url] link [url=http://25.x004.in/16.html]link[/url] link [url=http://24.x004.in/19.html]link[/url] link [url=http://09.x004.in/37.html]link[/url] link [url=http://41.x004.in/21.html]link[/url] link [url=http://35.x004.in/11.html]link[/url] link [url=http://27.x004.in/43.html]link[/url] link [url=http://01.x004.in]link[/url] link [url=http://32.x004.in/10.html]link[/url] link [url=http://20.x004.in/6.html]link[/url] link [url=http://29.x004.in/44.html]link[/url] link [url=http://48.x004.in/20.html]link[/url] link [url=http://46.x004.in/31.html]link[/url] link [url=http://26.x004.in/26.html]link[/url] link [url=http://06.x004.in/4.html]link[/url] link [url=http://04.x004.in/22.html]link[/url] link [url=http://16.x004.in/49.html]link[/url] link [url=http://31.x004.in/21.html]link[/url] link [url=http://11.x004.in/45.html]link[/url] link [url=http://00.x004.in/40.html]link[/url] link [url=http://00.x004.in/15.html]link[/url] link [url=http://11.x004.in/27.html]link[/url] link [url=http://36.x004.in/10.html]link[/url] link [url=http://36.x004.in/38.html]link[/url] link [url=http://17.x004.in/37.html]link[/url] link [url=http://08.x004.in/40.html]link[/url] link [url=http://10.x004.in/48.html]link[/url] link [url=http://24.x004.in/46.html]link[/url] link [url=http://46.x004.in/48.html]link[/url] link [url=http://33.x004.in/45.html]link[/url] link [url=http://21.x004.in/6.html]link[/url] link [url=http://26.x004.in/15.html]link[/url] link [url=http://41.x004.in/3.html]link[/url] link [url=http://23.x004.in/19.html]link[/url] link [url=http://25.x004.in/17.html]link[/url] link [url=http://29.x004.in/1.html]link[/url] link [url=http://12.x004.in/21.html]link[/url] link [url=http://25.x004.in/42.html]link[/url] link [url=http://46.x004.in/25.html]link[/url] link [url=http://45.x004.in/10.html]link[/url] link [url=http://48.x004.in/35.html]link[/url] link [url=http://02.x004.in/44.html]link[/url] link [url=http://32.x004.in/46.html]link[/url] link [url=http://22.x004.in/2.html]link[/url] link [url=http://25.x004.in/8.html]link[/url] link [url=http://15.x004.in/48.html]link[/url] link [url=http://21.x004.in/5.html]link[/url] link [url=http://49.x004.in/32.html]link[/url] link [url=http://47.x004.in/5.html]link[/url] link [url=http://04.x004.in/5.html]link[/url] link [url=http://39.x004.in/49.html]link[/url] link [url=http://02.x004.in/40.html]link[/url] link [url=http://45.x004.in/12.html]link[/url] link [url=http://07.x004.in/7.html]link[/url] link [url=http://01.x004.in/8.html]link[/url] link [url=http://20.x004.in/12.html]link[/url] link [url=http://30.x004.in/36.html]link[/url] link [url=http://26.x004.in/33.html]link[/url] link [url=http://15.x004.in/42.html]link[/url] link [url=http://21.x004.in/18.html]link[/url] link [url=http://15.x004.in/19.html]link[/url] link [url=http://44.x004.in/27.html]link[/url] link [url=http://32.x004.in/23.html]link[/url] link [url=http://02.x004.in/7.html]link[/url] link [url=http://19.x004.in/18.html]link[/url] link [url=http://00.x004.in/36.html]link[/url] link [url=http://17.x004.in/38.html]link[/url] link [url=http://23.x004.in/33.html]link[/url] link [url=http://28.x004.in/27.html]link[/url] link [url=http://16.x004.in/2.html]link[/url] link [url=http://38.x004.in/41.html]link[/url] link [url=http://02.x004.in/47.html]link[/url] link [url=http://48.x004.in/1.html]link[/url] link [url=http://08.x004.in/24.html]link[/url] link [url=http://28.x004.in/38.html]link[/url] link [url=http://14.x004.in/25.html]link[/url] link [url=http://32.x004.in/17.html]link[/url] link [url=http://28.x004.in/32.html]link[/url] link [url=http://22.x004.in/33.html]link[/url] link [url=http://45.x004.in/9.html]link[/url] link [url=http://43.x004.in/14.html]link[/url] link [url=http://13.x004.in/49.html]link[/url] link [url=http://29.x004.in/3.html]link[/url] link [url=http://45.x004.in/3.html]link[/url] link [url=http://07.x004.in/3.html]link[/url] link [url=http://47.x004.in/20.html]link[/url] link [url=http://26.x004.in/24.html]link[/url] link [url=http://05.x004.in/47.html]link[/url]

Leave a Reply