10 September 2007
This article is geared toward designers and developers working in the Flash authoring tool, who are looking for a solution involving no ActionScript.
Note: If you are working in Adobe Flex, or if you're looking for a more flexible and powerful (but more ActionScript-heavy) solution, there are several options. See the Using approaches based on Flex and ActionScript and Where to go from here sections for more information.
This article is largely based on one that I published on my website in December 2006: Deep linking to different frames/states in a Flash application. However, I've also had the good fortune of being able to improve this version by incorporating some of the great feedback that readers provided in response to the original. So to all of you who gave me feedback on that article, or any of my writing, thank you very much.
Adobe Flash is used to create interesting, compelling, and innovative user interfaces and websites. However, one common complaint about Flash-only websites is that they don't follow the web convention of "one URL per page." As we all know, one of the conventions of "how the web works" is that different sections or pages of a website have different URLs.
For example, if you give someone a URL for the contact page of your website, they can access that page directly by entering that URL in the browser's address bar. It's much cleaner than having to say, "Go to mysite.com, click About MyCompany, and click Contact Us." By contrast, if an entire website is built in a single FLA file in Flash, then when the file is published and the resulting SWF file is placed on a web page, there is only a single page—a single URL—to load in the browser for accessing the entire site. There is no way to access any section of the site directly.
Or suppose you create a SWF file that serves as a header or navigation bar for your website. You want to include the SWF file in multiple HTML (PHP or whatever) pages but you want the header image to change or the selected button in the navigation bar to be different according to which HTML page is being displayed in the browser.
This article describes several techniques for specifying different URLs that can be used to access different parts of a Flash-based website or Flash header/navigation bar.
Before going any further, I want to cover just a tiny bit of terminology to help you understand what is actually going to be covered in the article. While the title uses the term deep-linking, another way of describing this would be directly linking—linking to content that's "buried" within a site rather than only being able to link to the surface of the site's content. Another name for what I'm going to cover is creating RESTful URLs in Flash (or some variation on that). The key term here is REST ("representational state transfer"), which means having distinct URLs for directly linking to different content or different states of a web-based application.
Perhaps the easiest way to organize a Flash-based website is to use a different keyframe on the main Timeline to represent each "state" ("page" or "screen") of the site, as shown in Figure 1.
This is the organizational scheme that I'm going to assume for this article. In addition, as the title suggests, this article shows you how to create a Flash site that enables you to link directly to different frames in a Flash SWF file.
To start things off, we'll look at a way to link to frames that doesn't require you to write any ActionScript or other code at all, using what Flash calls frame anchors.
If you're somewhat familiar with HTML, you probably know that an anchor is like a link destination in a web page—it's how you specify a particular section in an HTML page, to which a link can point. For instance, if you want to have a link from part of an HTML page to a different place in the same page, or from one page to a specific place (other than the top) of a page, you use an anchor to accomplish that. (In fact, the
<a> tag that's used to create hyperlinks in HTML stands for "anchor" and the
<a> tag was originally used to create anchor destinations as well as links.)
The syntax for writing a URL to point to a particular anchor location in HTML is to use the pound sign (#) followed by the designated name for the anchor, as in the following examples:
A frame anchor is conceptually similar to an HTML anchor, except that rather than specifying a particular part of the HTML page as the destination to which anchor links will go, you specify a particular frame on the main Timeline and, when an anchor link is specified in the browser, it causes the playhead to jump to that frame automatically.
Flash does most of the work for making frame anchors function. You need to do two things in your FLA file to make it work:
If you've used frame labels in Flash—and if you haven't, you should be using them—adding a frame anchor works pretty much the same way as adding a frame label:
This creates a single anchor frame, with the name that you specify. As with frame labels and frame comments, the name appears in the Timeline with a special icon (a small ship's anchor) indicating that it's a frame anchor (see Figure 5).
Later, when a user accesses the page using a URL with an anchor name matching the name you specified in Step 2 (for example, my_home_page.html#about_us), the page will open and the SWF will move the playhead to the appropriate frame so that the content at the frame with the anchor name "about_us" is displayed.
This doesn't work automatically, however. There's one more important step that needs to be done: you need to publish the SWF with the appropriate template (the appropriate publish settings) so that the named anchors work:
Finally, let me suggest some strategies to use when you're working with this technique, some of which are also common recommendations for working with frame labels:
gotoAndStop("home")won't do anything if you have an anchor frame with the anchor name "home," unless you also have a frame with the label "home." (Naturally, to avoid confusing yourself, you'll want to make sure the keyframe with the label "home" corresponds to the same frame number as the keyframe with the anchor name "home.") Because you can't assign both a frame label and an anchor name to the same keyframe, you'll need to have two sets of two keyframes, on two different layers—one for named anchors and one for labels.
I intentionally chose to limit this article to the simplest approach—at least in terms of not needing to write any ActionScript. However, it does have some limitations. In particular, it ties you to the use of the Timeline and frames to differentiate between different screens/pages, so it doesn't work for more complex applications where the layout is often in nested movie clips on a single frame of the Timeline (or something completely different, like Flex MXML).
In addition, this approach is less "discoverable" for users because when the Timeline reaches a keyframe through some means other than an anchor URL—for example, when animation plays or the user clicks a button that triggers a
gotoAndStop() action—the browser's address bar doesn't update itself. Consequently, the website still behaves differently from a traditional HTML site—even though you know that the anchors are there, it's not obvious or easy for the user to figure out that the site has different URLs for different pages, or to know what those URLs are.
These disadvantages and others have been addressed by several techniques that have been shared with me. Note that I haven't tried most of these, so I can't vouch for their particular usefulness, but they all come highly recommended by others:
Using FlashVars and server code to dynamically switch frames is, in my opinion, the simplest approach that requires ActionScript. It is particularly useful if you've created a banner or navigation bar SWF that you want to reuse on multiple web pages with different URLs—and have it show different content for each page. In the original version of this article I went into some detail about the FlashVars approach; I've also written a separate article about FlashVars. Later I gave a presentation where I explained some details about how to use this approach.