Posts Tagged classe
ExternalInterface ou navigateToURL?
Posted by Renato Pacheco in ActionScript 3, JavaScript on 8 de setembro de 2009
Alguns desenvolvedores costumam se questionar sobre o uso do ExternalInterface no lugar navigateToURL para executar um JavaScript afinal de contas a classe existe para executar esta tarefa mas, será que não existem exceções?
Pode ser que você se lembre do getURL que até o Flash 7 era o nosso meio de comunicação com o navegador antes da chegada do ExternalInterface ainda no AS2 e que felizmente logo na seqüência, o getURL saiu de cena para dar lugar ao navigateToURL no AS3.
Passada por esta fase tornou-se obrigatório o uso do ExternalInterface e o navigateToURL foi deixado de lado para o uso exclusivo de acesso a links. Eu até concordaria, desde que todos os pontos fossem cobertos.
Vamos a um exemplo criando dois botões, um usando o ExternalInterface e outro usando navigateToURL para executar um JavaScript. Vou utilizar neste exemplo um script para adicionar a favoritos que encontrei no site codigofonte que funciona em vários navegadores.
JavaScript:
function addFav(title,url)
{
if (window.sidebar)
{
window.sidebar.addPanel(title, url,"");
}
else if(window.opera && window.print)
{
var mbm = document.createElement('a');
mbm.setAttribute('rel','sidebar');
mbm.setAttribute('href',url);
mbm.setAttribute('title',title);
mbm.click();
}
else if(document.all)
{
window.external.AddFavorite(url, title);
}
}
Agora no Flash, fiz dois botões:
![]()
Cada um executando o mesmo JavaScript de maneiras diferentes:
ActionScript:
// Importando as classes que vamos utilizar.
import flash.external.ExternalInterface;
import flash.net.navigateToURL;
// Vamos definir o título do favorito.
var titulo:String = "Renato Pacheco";
// Aqui, definimos a url do favorito.
var url:String = "http://www.renatopacheco.com.br";
// Juntando os dois dados acima, montamos um JavaScript covencional.
// Poderiamos usar até em um link de página HTML.
// É muito importante usar a função void(0) para anular o retorno da função qe vamos executar.
var javaScript:String = "javascript:addFav('" + titulo + "','" + url+ "');void(0);";
// Aplicando a um dos botões a função ExternalInterface.
ExtIntBtn.addEventListener(MouseEvent.CLICK,function($e:MouseEvent):void{
ExternalInterface.call("addFav",titulo,url);
});
// Aplicando ao outro botão o navigateToURL.
NavToUrlBtn.addEventListener(MouseEvent.CLICK,function($e:MouseEvent):void{
navigateToURL(new URLRequest(javaScript),"_self");
});
Ao colocar o SWF na mesma página que o código JavaScript e clicar em qualquer um dos botões aparentemente temos quase o mesmo resultado:

A primeira vista temos o mesmo resultado, mas não podemos esquecer que esta ação depende do usuário para ser concluída.
No caso do navigateToURL não faz diferença pois o flash continuará sua execução normalmente mas, para o ExternalInterface a história não é bem assim. Quando é executado o ExternalInterface.call() espera um retorno do javascript seja ele nulo ou não, então espere que o usuários demore uns quinze segundos para terminar a ação e veja o que acontece:

Você pode até achar que isso não acontece e que ninguém vai levar mais de quinze segundos para adicionar um link aos favoritos, pois eu lhe digo que já aconteceu e não interessa sua justificativa, o cliente vai entrar em pânico quando vir uma mensagem dessa.
Por isso eu pensaria duas vezes antes de tornar o uso de o ExternalInterface uma regra indiscutível e a prova de falhas.