Flash + XML 动态导航菜单教程

这个教程的核心思想是:将导航菜单的内容(如链接名称、URL)与 Flash 的展示逻辑分离,XML 文件负责存储数据,Flash 读取并解析这些数据,然后动态生成菜单,这样做的好处是,未来修改菜单内容时,你只需要编辑 XML 文件,而无需重新打开和发布 Flash 文件。

flash xml 导航教程
(图片来源网络,侵删)

最终效果

我们将创建一个水平的导航菜单,当鼠标悬停时,菜单项会有一个放大的动画效果。


第一步:准备 XML 数据文件

我们需要一个 XML 文件来定义我们的导航菜单内容。

  1. 创建一个新的文本文件。
  2. 将其命名为 navigation.xml
  3. 复制并粘贴到文件中:
<?xml version="1.0" encoding="UTF-8"?>
<nav>
    <item>
        <label>首页</label>
        <url>index.html</url>
    </item>
    <item>
        <label>关于我们</label>
        <url>about.html</url>
    </item>
    <item>
        <label>服务项目</label>
        <url>services.html</url>
    </item>
    <item>
        <label>产品展示</label>
        <url>products.html</url>
    </item>
    <item>
        <label>联系我们</label>
        <url>contact.html</url>
    </item>
</nav>

代码解释:

  • <?xml ... ?>: XML 声明,定义了 XML 版本和编码。
  • <nav>: 根元素,包裹所有的菜单项。
  • <item>: 每一个菜单项都是一个 <item> 元素。
  • <label>: 菜单项上显示的文本。
  • <url>: 点击菜单项后要跳转到的链接地址。

navigation.xml 文件保存到你的 Flash 项目文件夹中。

flash xml 导航教程
(图片来源网络,侵删)

第二步:准备 Flash 文件

我们打开 Adobe Flash (以 ActionScript 3.0 为例)。

  1. 打开 Flash,创建一个新的 ActionScript 3.0 文档。
  2. 设置舞台大小,800x600 像素。
  3. 保存文件,例如命名为 main.fla,并确保它和 navigation.xml 在同一个文件夹下。

第三步:在 Flash 中创建导航菜单组件

我们将使用一个简单的 MovieClip 作为菜单项的模板。

  1. 在舞台上,使用 文本工具 创建一个静态文本,输入 "Menu Item" 作为占位符,选择这个文本,按 F8 将其转换为 影片剪辑
  2. 在弹出的“转换为元件”对话框中,命名为 MenuItem,勾选 “为 ActionScript 导出”,并在 “类” 框中输入 MenuItem,Flash 会自动为你创建一个链接。
  3. 双击进入 MenuItem 的编辑模式,删除舞台上的 "Menu Item" 文本。
  4. 在这个新的图层上,创建一个简单的矩形作为背景,你可以给它一个填充色(比如灰色)。
  5. 在背景矩形上方,新建一个图层,创建一个文本框,在属性面板中,将其设置为 动态文本,实例名称命名为 label_txt
  6. 返回到主场景(场景1),删除舞台上刚刚创建的那个 MenuItem 实例,我们只需要它的“模板”,不需要它出现在初始舞台上。

第四步:编写 ActionScript 3.0 代码

这是整个教程的核心部分,我们将代码写在主场景的第 1 帧。

  1. 在主场景的第 1 帧,按 F9 打开 “动作” 面板。
  2. 将以下代码复制并粘贴进去:
// 1. 设置变量
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
// 2. 加载 XML 文件
// 确保文件路径正确,这里使用相对路径
xmlLoader.load(new URLRequest("navigation.xml"));
// 3. 添加事件监听器
// 当 XML 文件开始加载时
xmlLoader.addEventListener(Event.OPEN, showLoading);
// 当 XML 文件加载完成时
xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
// 当加载出错时
xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, xmlLoadError);
// 4. 定义事件处理函数
function showLoading(e:Event):void {
    trace("正在加载 XML 文件...");
    // 可以在这里添加一个加载提示,例如在舞台上显示 "Loading..."
}
function xmlLoadError(e:IOErrorEvent):void {
    trace("加载 XML 文件出错: " + e.text);
}
function xmlLoaded(e:Event):void {
    trace("XML 文件加载成功!");
    // 将加载的数据解析为 XML 对象
    xmlData = new XML(e.target.data);
    // 开始创建菜单
    createMenu();
}
// 5. 创建菜单的函数
function createMenu():void {
    // 设置菜单的起始位置和间距
    var startX:Number = 50;
    var startY:Number = 50;
    var spacing:Number = 10; // 菜单项之间的间距
    // 遍历 XML 中的每个 <item> 节点
    for each (var menuItem:XML in xmlData.item) {
        // 获取标签和URL
        var label:String = menuItem.label;
        var url:String = menuItem.url;
        // 创建一个新的菜单项(从库中)
        var item:MenuItem = new MenuItem();
        // 设置动态文本的内容
        item.label_txt.text = label;
        // 设置菜单项的位置
        item.x = startX;
        item.y = startY;
        // 为菜单项添加鼠标事件
        item.buttonMode = true; // 鼠标悬停时显示手型光标
        item.addEventListener(MouseEvent.ROLL_OVER, onRollOver);
        item.addEventListener(MouseEvent.ROLL_OUT, onRollOut);
        item.addEventListener(MouseEvent.CLICK, onMenuItemClick);
        // 将URL存储在菜单项实例中,以便点击时使用
        item.url = url;
        // 将菜单项添加到显示列表中
        addChild(item);
        // 更新下一个菜单项的 X 坐标
        // item.width 获取菜单项的宽度,label_txt.textWidth 获取文本的宽度
        // 这里使用 item.width 更准确,因为它包含了背景
        startX += item.width + spacing;
    }
}
// 6. 定义菜单项的交互函数
function onRollOver(e:MouseEvent):void {
    // 获取当前鼠标悬停的菜单项
    var item:MenuItem = e.currentTarget as MenuItem;
    // 使用 TweenLite 或简单的缩放来实现动画效果
    // 这里我们使用简单的缩放
    item.scaleX = 1.2;
    item.scaleY = 1.2;
    // 调整位置,使其以中心点放大
    item.x -= item.width * 0.1; // (1.2 - 1) / 2 = 0.1
    item.y -= item.height * 0.1;
}
function onRollOut(e:MouseEvent):void {
    var item:MenuItem = e.currentTarget as MenuItem;
    item.scaleX = 1;
    item.scaleY = 1;
    // 恢复位置
    item.x += item.width * 0.1;
    item.y += item.height * 0.1;
}
function onMenuItemClick(e:MouseEvent):void {
    var item:MenuItem = e.currentTarget as MenuItem;
    var targetURL:String = item.url;
    trace("你点击了: " + targetURL);
    // 使用 navigateToURL 在新窗口打开链接
    // _blank 表示在新窗口打开
    navigateToURL(new URLRequest(targetURL), "_blank");
}

第五步:测试

  1. 确保 main.flanavigation.xml 在同一个文件夹下。
  2. Ctrl + Enter (Windows) 或 Cmd + Enter (Mac) 来测试你的影片。

你应该会看到一个水平排列的导航菜单,当你的鼠标移到菜单项上时,它会放大,点击它则会在新浏览器标签页中打开对应的链接。

flash xml 导航教程
(图片来源网络,侵删)

代码解析与进阶

  • URLLoaderXML: URLLoader 负责从外部加载文件(如 XML、图片、文本等),加载完成后,数据会以字符串形式存储,我们使用 new XML(e.target.data) 将这个字符串转换成 Flash 可以方便操作的 XML 对象。
  • for each...in 循环: 这是遍历 XML 节点最简洁的方式。for each (var menuItem:XML in xmlData.item) 会循环访问 xmlData.item 下的每一个 <item> 节点,并将当前节点赋值给 menuItem 变量。
  • e.currentTarget: 在事件处理函数中,e.currentTarget 指的是触发事件的那个对象本身(在这里就是被点击或悬停的那个 MenuItem 实例),这比 e.target 更可靠,因为 e.target 可能是对象内部的子对象(比如文本框)。
  • buttonMode = true: 这是一个非常方便的属性,它会让一个显示对象(通常是 MovieClip)在鼠标悬停时自动显示手型光标,并使其可以接收鼠标事件,就像一个按钮一样。
  • navigateToURL: 这是 AS3 中打开网页的标准函数,第一个参数是 URLRequest 对象,包含要打开的 URL;第二个参数是目标窗口,"_self" 表示在当前窗口打开,"_blank" 表示在新窗口打开。

进阶建议

  1. 美化动画: 使用 TweenLite/TweenMax 等第三方动画库,可以实现更平滑、更复杂的动画效果,而不是简单的缩放。
  2. 添加子菜单: 你可以扩展 XML 结构,在 <item> 内部添加 <subitem>,然后在 Flash 中通过检测鼠标悬停时间或点击事件来动态创建和显示子菜单。
  3. 使用外部类: 将所有代码都写在时间轴上不利于项目管理和复用,你可以将 MenuItem 的逻辑(如事件处理)写在一个单独的 .as 文件中,使代码结构更清晰。
  4. 错误处理: 可以添加一个加载失败的提示,而不是仅仅在输出面板打印错误信息,提升用户体验。

这个教程为你提供了一个坚实的基础,你可以基于这个框架进行扩展和修改,创建出更复杂、更精美的动态导航系统。