Você conhece o SWFAddress?

Um dos maiores problemas que o usuário enfrenta ao acessar um site feito para a plataforma Flash Player, é o fato de o histórico do browser não existir, e os botões de navegação do mesmo não funcionarem.

Aquela história de mandar um link para um amigo, apontando diretamente para o conteúdo em questão, simplesmente não existe. E é algo comum na maioria dos sites feitos para o Flash Player.

Mas nem tudo está perdido. Faz um bom tempo que existe uma solução para este problema, que se chama SWFAddress.

O SWFAddress é uma pequena biblioteca que permite que o Flash crie um histórico de acesso de seu conteúdo no browser. Isto significa que você tem a funcionalidade dos botões back e forward mesmo estando no Flash. Claro, não é a mesma coisa, mas o resultado é bastante satisfatório.

O caso é que, mesmo existindo a solução pouca gente usa, o que acaba prejudicando a experiência do usuário, pois algo que ele está acostumado simplesmente não funciona naquele site.
O objetivo deste é mostrar o funcionamento do SWFAddress, e como é simples implementá-lo em seu site. E então, vamos lá?

O Modelo

Primeiro passo, baixe o modelo que iremos utilizar. Este modelo já contém a versão 2.4 do SWFAddress, mas fique livre para conferir se existe uma nova versão no site.

O modelo contém uma pequena aplicação já funcionando, trata-se de uma página com 3 itens de menu, ao clicar sobre um item, um SWF representando uma seção é carregado.
O nosso objetivo é implementar o SWFAddress nesta pequena aplicação, de modo que possamos utilizar os botões back e forward do browser, e outras vantagens mais.

No modelo temos a seguinte estrutura de arquivos:

  • bin – pasta contendo os binários.
  • src – pasta contendo os arquivos de produção.
    • about.fla – seção about.
    • app – pacote contendo os arquivos da nossa aplicação.
      • ApplicationContent.as
      • navigation
        • NavItem.as
    • com – pacote contendo arquivos de terceiros.
      • asual
        • SWFAddress.as
        • SWFAddressEvent.as
    • contact.fla – seção contact.
    • home.fla – seção home.
    • index.fla – arquivo principal.

Como pode ver são poucos arquivos. Dentro do arquivo ApplicationContent.as nós temos alguns métodos privados. Esta classe é vinculada ao arquivo index.fla. Através dela criamos os itens de menu e carregamos os arquivos de conteúdo.

Ela contém 4 métodos:

  • createMenu() – Cria os itens de navegação. Neste método nós adicionamos o evento CLICK aos itens conforme eles vão sendo criados.
  • loadContent(filePath:String) – Carrega o arquivo especificado em filePath.
  • handleLoaderComplete(event:Event) – Disparado quando o carregamento do arquivo é finalizado, adiciona o conteúdo carregado ao palco.
  • handleNavItemClick(event:MouseEvent) – Disparado quando um item do menu é clicado, inicializa o carregamento da seção relacionada com o botão clicado.

A classe NavItem.as é a classe que representa os nossos botões de navegação. Ela contém propriedades como file e label. Não se tem muito para falar dela.

Dentro de ApplicationContent, nós definimos um pequeno XML contendo as seções. A partir deste XML os botões são gerados. Devido a natureza deste exemplo ser simples, eu coloquei a estrutura do XML dentro do AS mesmo, mas ele poderia estar em um arquivo externo sem problemas.

Implementando o SWFAddress

Se você testou o exemplo a partir do HTML (que se encontra dentro da pasta bin) pode ver que ao clicarmos nos itens do menu, nada acontece no browser. A nossa missão agora é implementarmos o SWFAddress para mudarmos isso.

O primeiro passo é adicionarmos o SWFAddress em nossa aplicação. Isso é feito de forma bem simples, abra o arquivo ApplicationContent.as e dentro do método construtor ApplicationContent você adiciona, logo após a chamada super():

1
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleSWFAddressChange);

A classe SWFAddress é um classe estática, ou seja, não se cria uma instância dela, e todos os métodos que ela contém são estáticos. Por isso nós simplesmente adicionamos o evento, diretamente na classe.

O próximo passo é criar o método handleSWFAddressChange que nós citamos como listener do evento CHANGE.

1
2
3
4
5
6
7
8
9
10
/**
 * @private
 * Handler do evento CHANGE, disparado quando o valor do SWFAddress é alterado.
 *
 * @param event SWFAddressEvent
 */

private function handleSWFAddressChange(event:SWFAddressEvent):void
{
    trace("URL CHANGED");
}

O evento CHANGE é disparado sempre que ocorre uma alteração no path do SWFAddress. Este path é utilizado na url para criar o histórico e etc. O evento sempre dispara no começo, afinal, você sempre digita um endereço para entrar no site. Portanto, é neste handler que nós iremos verificar a urlatual, e qual conteúdo devemos carregar.

Deixemos um pouco de lado esta parte do handler. Nós precisamos adicionar um pequeno detalhe ao nosso XML. Atualmente, a estrutura dele é esta:

1
2
3
4
5
6
7
8
9
/**
 * @private
 * XML contendo as seções existentes.
 */

private var _sections:XML = <sections>
    <section file="home.swf" label="Home" />
    <section file="about.swf" label="About" />
    <section file="contact.swf" label="Contact" />
</sections>

Temos apenas duas informações, o caminho para o arquivo e o rótulo da seção. Falta a gente definir a tag da seção que será exibida na url, de forma que ao acessarmos Contact por exemplo, nossa url fique algo como http://www.meusite.com.br/#/contact/. Assim sendo:

1
2
3
4
5
6
7
8
9
/**
 * @private
 * XML contendo as seções existentes.
 */

private var _sections:XML = <sections>
    <section file="home.swf" tag="home" label="Home" />
    <section file="about.swf" tag="about" label="About" />
    <section file="contact.swf" tag="contact" label="Contact" />
</sections>

Uma vez definida a tag, vamos adicionar este valor aos nossos botões. Na classe NavItem, adicione a seguinte propriedade:

1
2
3
4
5
/**
 * @private
 * Tag da seção.
 */

private var _tag:String;

E os métodos de get e set:

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * Tag da seção.
 */

public function get tag():String
{
    return this._tag;
}

public function set tag(value:String):void
{
    this._tag = value;
}

No próximo passo, nós iremos alterar o método createMenu da classe ApplicationContent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * @private
 * Cria o menu de navegação.
 */

private function createMenu():void
{
    this._menuItems = [];
    var xIni:int = 20;
   
    for each (var section:XML in this._sections.children())
    {
        var navItem:NavItem = new NavItem();
        navItem.file = section.@file;
        navItem.label = section.@label;
        navItem.tag = section.@tag;
       
        navItem.x = xIni;
        navItem.y = 20;
        xIni += navItem.width + 10;
       
        this._menuItems.push(navItem);
        this.addChild(navItem);
    }
}

Adicionamos o valor da tag ao botão. Também removemos o listener do evento CLICK, pois passaremos a ouvir este evento a partir da classe NavItem, e removemos a chamada ao método loadContent que não será mais necessário, uma vez que iremos implementar esta chamada no handler do evento CHANGE do SWFAddress (lembra?).

Feito isso, o próximo passo é implementarmos o evento CLICK em nossa classe NavItem:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * Cria uma instancia de <code>NavItem</code>.
 */

public function NavItem()
{
    super();
   
    this.buttonMode = true;
    this.mouseChildren = false;
   
    // Adicionando evento CLICK.
    this.addEventListener(MouseEvent.CLICK, this.handleClick);
}

E o método handleClick:

1
2
3
4
5
6
7
8
9
10
/**
 * @private
 * Handler do evento CLICK, disparado quando o botão é clicado.
 *
 * @param event MouseEvent
 */

private function handleClick(event:MouseEvent):void
{
   
}

Este cara será disparado toda vez que o botão for clicado. E o que nós temos que fazer quando o botão for clicado é bem simples, muda a url para que o conteúdo seja carregado. A lógica é um pouco diferente aqui, pois ao invés de chamarmos um método para carregar o conteúdo, nós alteramos o valor do SWFAddress, e através do evento CHANGE dele é que o conteúdo será carregado.

1
2
3
4
5
6
7
8
9
10
/**
 * @private
 * Handler do evento CLICK, disparado quando o botão é clicado.
 *
 * @param event MouseEvent
 */

private function handleClick(event:MouseEvent):void
{
    SWFAddress.setValue('/' + this.tag);
}

A grande sacada do setValue, é que você pode chamá-lo de onde estiver, não importa o nível hierárquico. Isto facilita muito a vida quando precisamos de elementos com links para páginas, mas que não pertençam ao menu, basta chamar o setValue e pronto, o nosso handler vai escutar e carregar a página.

Se você testar o filme e clicar em um botão, verá na janela de saída o texto "URL CHANGED" para cada clique. Agora falta implementarmos a troca de conteúdo dentro do método handleSWFAddressChange da classe ApplicationContent.

A primeira coisa que temos que fazer é obter a path atual do SWFAddress. Nós temos acesso a este valor através do método SWFAddress.getPathNames() ou através do parâmetro event.pathNames:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * @private
 * Handler do evento CHANGE, disparado quando o valor do SWFAddress é alterado.
 *
 * @param event SWFAddressEvent
 */

private function handleSWFAddressChange(event:SWFAddressEvent):void
{
    var pathNames:Array = event.pathNames;
   
    if (event.pathNames.length == 0)
        pathNames = ['home'];
}

Obtemos o path e em seguida verificamos se existe alguma tag nele, pois caso não exista, nós definimos home como sendo o conteúdo inicial.

Também vale mencionar o método SWFAddress.getPath() que nos traz uma string contendo todo o caminho. A diferença entre ele e getPathNames é essa, um traz um array com cada tag separada e o outro uma string.

Agora que temos as tags do nosso path, temos que criar um método para obter o NavItem relacionado aquela tag, para que então possamos obter o caminho para o arquivo a ser carregado.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 *  @private
 *  Obtém o NavItem de acordo com a tag passada.
 */

private function getNavItemFromPath(tag:String):NavItem
{
    for each (var item:NavItem in this._menuItems)
    {
        if (item.tag == tag)
            return item;
    }
   
    return null;
}

Esta é uma implementação simples, no caso de uma navegação com sub-itens, seria interessante passar o array com todas as tags, e fazer uma recursão até encontrar o botão.

Voltando ao nosso handler, vamos fazer a verificação do path, caso exista um valor válido a gente exibe o conteúdo correto, e caso não, exibiremos um conteúdo default, no nosso caso a seção home.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @private
 * Handler do evento CHANGE, disparado quando o valor do SWFAddress é alterado.
 *
 * @param event SWFAddressEvent
 */

private function handleSWFAddressChange(event:SWFAddressEvent):void
{
    var pathNames:Array = event.pathNames;
   
    if (event.pathNames.length == 0)
        pathNames = ['home'];
   
    var navItem:NavItem = this.getNavItemFromPath(pathNames[0]);
   
    if (!navItem)
        navItem = this.getNavItemFromPath('home');
       
    this.loadContent(navItem.file);
}

Pronto, obtemos o botão relacionado a tag e efetuamos o carregamento do arquivo.
A parte que diz respeito ao Flash está finalizada. Agora falta um pequeno detalhe, que é incluir a biblioteca javascript do SWFAddress.

Vá na pasta bin do nosso projeto, e abra o arquivo index.html. Dentro da tag head nós iremos inserir o caminho para o arquivo javascript swfaddress.js, que se encontra dentro da pasta js.

1
2
3
4
5
6
7
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Meu Site</title>
    <meta name="author" content="Mozart Petter">
    <script src="js/swfobject.js" type="text/javascript"></script>
    <script src="js/swfaddress.js" type="text/javascript"></script>
</head>

Abra o arquivo html em seu browser, mas para visualizar corretamente você deve abri-lo a partir de um servidor (local ou hospedado, tanto faz).
Você pode conferir o exemplo em funcionamento aqui.

Esta foi uma simples implementação, a biblioteca proporciona muitas outras opções. O SWFAddress é uma ótima biblioteca, que além de melhorar a vida do usuário, nos ajuda também a simplificar o modelo de navegação do nosso site. Espero que tenham gostado e deixem sua opinião no espaço para comentários.

5 Comments

  1. Por favor, coloque o arquivo para Download. agradeço.

  2. Mozart Petter

    Problema corrigido, o arquivo agora se encontra disponível. :)

  3. Luiz Paulo

    Mozart Obrigado pela ajuda! Procurei muito na internet e não achei nada. Graças a você estou compreendendo melhor o swfadress.

  4. robertolima

    poxa achei muito interessante mas nao consegui fazer rodar o address,
    como faço para conseguir o fonte completo, para estudo, agradeço

  5. robertolima

    vc consegui os arquivos

Leave a Comment