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
- asual
- 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.
Por favor, coloque o arquivo para Download. agradeço.
Problema corrigido, o arquivo agora se encontra disponível. :)
Mozart Obrigado pela ajuda! Procurei muito na internet e não achei nada. Graças a você estou compreendendo melhor o swfadress.
poxa achei muito interessante mas nao consegui fazer rodar o address,
como faço para conseguir o fonte completo, para estudo, agradeço
vc consegui os arquivos