сряда, 1 януари 2014 г.

SWFObject: inserção e detecção do Flash Player via Javascript

O SWFObject é um pequeno arquivo Javascript usado para a inserção de conteúdo Macromedia Flash na página. O script detecta o plug-in do Flash em todos os principais navegadores (do Mac e PC), e foi projetado para facilitar ao máximo a inserção de filmes em Flash. É “amigável” aos mecanismos de busca, mostra um conteúdo alternativo no caso de o filme não ser carregado, pode ser usado em documentos HTML e XHTML 1.0 válidos* e é compatível no futuro, então se espera que ele funcione por muitos anos. Esta página é uma tradução livre que fiz da original de Geoff Stearns, com a permissão do autor.

* Páginas enviadas como text/html, e não application/xhtml+xml.

Atenção: o SWFObject é o script anteriormente conhecido como FlashObject. O nome foi alterado devido à razões legais de marca registrada. Para maiores informações, veja este post.

Sumário

Novidades nesta versão


Para uma lista completa de mudanças, por favor veja o post no blog: SWFObject 1.4

Funcionamento do script


[Os über nerds podem ver o javascript cru aqui.]

O uso do SWFObject é fácil. Simplesmente inclua o arquivo Javascript swfobject.js, então use uma pequena quantidade de script na sua página para inserir o filme Flash. Abaixo, segue um exemplo mostrando a quantidade mínima de código necessária para isso:
<script type="text/javascript" src="swfobject.js"></script>

<div id="flashcontent">
Este texto será substituído pelo filme Flash.
</div>

<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");
so.write("flashcontent");
</script>

Aqui está uma análise do que o código faz:
<div id="flashcontent">[...]</div>

Prepara um elemento HTML que armazenará o seu filme Flash. O conteúdo colocado no elemento “recipiente” (conteúdo alternativo) será substituído pelo conteúdo em Flash, assim os usuários com o plug-in do Flash instalado jamais verão o conteúdo dentro deste elemento. Esse recurso tem o bônus adicional de permitir aos mecanismos de busca indexar o seu conteúdo alternativo.

var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");

Cria um novo SWFObject passando os parâmetros obrigatórios:

  • swf: o caminho e o nome do seu arquivo swf.
  • id: o ID do seu objeto ou da tag “embed”. A tag embed também usará esse valor no seu atributo nome para os arquivos que utilizam o swliveconnect.
  • width: a largura (em pixels) do seu filme Flash.
  • height: a altura (em pixels) do seu filme Flash.
  • version: a versão necessária para rodar o seu conteúdo em Flash. Pode ser uma string no formato “maiorVersão.menorVersão.revisão”. Por exemplo: “6.0.65”. Ou você pode apenas exigir a maior versão, como por exemplo “6”.
  • background-color: o valor em hexa da cor de fundo do seu filme Flash.

Parâmetros opcionais:

  • useExpressInstall: se você deseja atualizar o plug-in dos usuários usando o recurso ExpressInstall, use “true” para esse valor.
  • quality: a qualidade com a qual você deseja que seu filme seja executado. O valor padrão é “high”.
  • xiRedirectUrl: se você deseja redirecionar os usuários que completarem uma atualização via ExpressInstall, especifique a URL aqui.
  • redirectUrl: se você deseja redirecionar os usuários que não têm a versão correta do plug-in, use esse parâmetro.
  • detectKey: o nome da variável de URL que o script do SWFObject procurará para contornar a detecção. O padrão é “detectflash”. Por exemplo: para contornar a detecção do Flash e simplesmente escrever o filme Flash na página, você pode adicionar ?detectflash=false na URL do seu documento que contém o filme Flash.

so.write("flashcontent");

Diz ao script do SWFObject para escrever o conteúdo em Flash na página (se a versão correta do plug-in estiver instalada no sistema do usuário), substituindo o conteúdo dentro do elemento HTML especificado.

Os detalhes


O SWFObject funciona silenciosamente no segundo plano do seu documento HTML. Ao desenvolver páginas que usam esse script, você começará criando o conteúdo alternativo (não-Flash). Faça que suas páginas funcionem sem os filmes em Flash, então os adicione com pequenos fragmentos Javascript que substituem seu conteúdo alternativo com os filmes desejados. Isso garante que o conteúdo alternativo será indexado pelos mecanismos de busca, e que os usuários sem o plug-in do Flash verão uma página HTML que funciona. Se você fornecerá instruções de upgrade ou não é uma decisão sua. Se o seu conteúdo alternativo é suficiente, pode não existir razão bastante para dizer às pessoas que elas estão perdendo o conteúdo em Flash.

O SWFObject funciona em todos os navegadores atuais, incluindo, em PC: IE5/5.5/6, Netscape 7/8, Firefox, Mozilla e Opera. No Mac: IE5.2, Safari, Firefox, Netscape 6/7, Mozilla e Opera a partir do 7.5. E é esperado que continue a funcionar no futuro.

O SWFObject detecta versões do Flash player, a partir da versão 3, nesses navegadores, e permitirá aos usuários interagir com seu conteúdo em Flash sem ter que “ativá-lo” primeiro. Para mais informações a respeito, veja este post sobre a disputa de patente Eolas no Internet Explorer.

O SWFObject detecta as versões menores e revisões do Flash player, basta informar um parâmetro com a string da versão desejada. Por exemplo, para exigir o Flash player v.6.0 r65 (ou 6,0,65,0):
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "6.0.65", "#336699");

A detecção de plug-in embutida do SWFObject pode ser contornada. Se um novo navegador for lançado, ou se, por alguma razão, a detecção falhar no sistema do usuário, você pode fornecer um link que desabilita essa detecção e sempre escreve o conteúdo em Flash na página. Para usar o link de contorno, faça um link para a sua página que inclua uma variável de URL chamada “detectflash”, configurada para “false”. Aqui está um exemplo de como pode ser esse link:
<a href="mypage.html?detectflash=false">Link de contorno</a>

Exemplos do SWFObject


O exemplo acima exposto é o necessário para o uso mínimo do SWFObject, mas, se você deseja usar outros parâmetros suportados pelo plug-in do Flash, o SWFObject facilita seu trabalho. Os exemplos abaixo mostram vários métodos diferentes que você pode desejar para inserir seu conteúdo em Flash.

Um exemplo simples de adição de parâmetros extras:

<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100%", "7", "#336699");
so.addParam("quality", "low");
so.addParam("wmode", "transparent");
so.addParam("salign", "t");
so.write("flashcontent");
</script>

Aqui está uma lista completa dos parâmetros atuais e seus possíveis valores da macromedia.com.

Passando variáveis para seus filmes usando parâmetros “Flashvars”


O uso de Flashvars é o modo mais fácil de pegar dados do HTML dentro do filme Flash, mas os dados são passados só uma vez, assim que o filme carrega. Normalmente, você adicionaria um parâmetro chamado “flashvars” e, para o valor, passaria uma string de pares nome/valor como esta: variavel1=valor1&variavel2=valor2&variavel3=valor3 e assim por diante. O SWFObject facilita isso, permitindo que sejam adicionadas tantas variáveis quanto você deseja, num modo similar ao que você usaria para passar parâmetros adicionais. Aqui está um exemplo de como passar valores para o seu filme Flash usando Flashvars:

<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");
so.addVariable("variavel1", "valor1");
so.addVariable("variavel2", "valor2");
so.addVariable("variavel3", "valor3");
so.write("flashcontent");
</script>

Fazendo isso, todas as variáveis que você passar estarão imediatamente disponíveis dentro do seu filme em Flash, na linha de tempo _root.

O script SWFObject também tem uma função extra que lhe permite buscar variáveis da URL. Por exemplo, suponha que você tenha a seguinte URL: http://www.example.com/page.html?variavel1=valor1&variavel2=valor2. Usando a função getQueryParamValue(), você pode facilmente pegar esses valores da URL e passá-los ao seu filme em Flash. Aqui está um exemplo para a supracitada URL:

<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");
so.addVariable("variavel1", getQueryParamValue("variavel1"));
so.addVariable("variavel2", getQueryParamValue("variavel2"));
so.write("flashcontent");
</script>

A função getQueryParamValue() também suporta a leitura de variáveis do location.hash, que às vezes são usadas para criar links profundos (deep links) para as suas aplicações Flash. Um exemplo de como criar links profundos para seus filmes Flash usando location.hash, veja este exemplo do Slideshow Pro, que usa inserção via SWFObject.

Usando o ExpressInstall


O SWFObject tem suporte completo ao recurso Macromedia Flash Player Express Install. Junto com o script SWFObject existe um arquivo actionscript que funciona com o SWFObject, para dar início a um processo de atualização de plug-in nos seus filmes Flash. Seus usuários nunca terão que deixar seu site para atualizar seus players, e quando a atualização estiver completa, eles serão redirecionados de volta à página que iniciou a atualização.

Para usar o ExpressInstall, você precisa primeiro incluir o arquivo expressinstall.as no seu .fla e, no início do seu filme, fazer uma simples checagem para ver se o plug-in do usuário precisa ser atualizado:

#include "expressinstall.as"

var ExpressInstall = new ExpressInstall();

// se o usuario precisa ser atualizado, mostra o botao “iniciar atualizacao”
if (ExpressInstall.needsUpdate) {

// isto eh opcional, vc pode tambem iniciar a atualizacao automaticamente,
// chamando ExpressInstall.init() aqui, ao inves das seguintes linhas

// anexa a msg personalizada de atualizacao, centralizada
var upgradeMsg = attachMovie("upgradeMsg_src", "upgradeMsg", 1);
upgradeMsg._x = Stage.width / 2;
upgradeMsg._y = Stage.height / 2;

// anexa as acoes de botao q iniciarao o atualizador ExpresInstall
upgradeMsg.upgradeBtn.onRelease = function() {
// este metodo eh o q dah inicio a atualizacao
ExpressInstall.init();
}
// se o expressinstall foi invocado, para a linha do tempo
stop();
}

É importante não colocar nenhum conteúdo no primeiro quadro (ou onde a checagem do ExpressInstall acontecer) que exija o Flash Player 7 ou superior.

Para um exemplo “ao vivo” deste código, abra o arquivo source/so_tester.fla incluído no arquivo SWFObject.zip. Ou, se você deseja ver o ExpressInstall em funcionamento, instale o Flash Player 7* (ou 6.0.65 adiante) e visite esta página.

* Se você já tem o plug-in Flash Player mais atual, e deseja testar o ExpressInstall (ou se deseja testar seu filme Flash em outras versões de plug-in), você precisa desinstalar seu plug-in atual e, em seguida, instalar a versão apropriada.

Se o seu filme Flash é uma janela popup, ou se você deseja redirecionar o usuário para um local diferente depois que a atualização ExpressInstall terminar, use o atributo xiRedirectUrl.

<script type="text/javascript">
var so = new SWFObject("movie.swf", "mymovie", "200", "100", "8", "#336699", true);
so.setAttribute('xiRedirectUrl', 'http://www.example.com/upgradefinished.html'); // precisa ser uma URL absoluta para o seu site
so.write("flashcontent");
</script>

Download


O SWFObject está liberado sobre a licença MIT. Isso significa (basicamente) que você pode usá-lo para qualquer coisa que você desejar, sem restrições.

Baixe o SWFObject 1.4 – Arquivo zip, incluindo swfobject.js e os modelos html abaixo.

Ou, se preferir, veja minhas páginas de exemplo:


* Páginas enviadas como text/html, e não application/xhtml+xml.

Assine também a lista de discussão do SWFObject. Ela tem como objetivo responder questões sobre problemas que você possa ter enquanto usa o SWFObject, ou para solicitar e discutir novos recursos.

Por que ele é melhor do que o resto


Através dos tempos, surgiram muitos métodos para a detecção da versão do Flash player e inserção dos filmes Flash em documentos HTML. Esta seção analisará cada um dos métodos mais populares e apontará os problemas em cada um deles.

1. A inserção padrão fornecida pela Macromedia


Todo mundo conhece a inserção padrão fornecida pela Macromedia. Ela consiste de uma tag Object com uma tag Embed introduzida como um mecanismo de alternativa no caso de falha. Este é o método de inserção de Flash mais popular e é a escolha padrão quando você publica seu filme Flash através da IDE do Macromedia Flash. É também o método mais compatível para inserir um filme em Flash, e vai funcionar na mais ampla gama de navegadores. Aqui está um exemplo do código padrão de inserção de Flash:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"
width="550" height="400" id="Untitled-1" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="mymovie.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="mymovie.swf" quality="high" bgcolor="#ffffff" width="550"
height="400" name="mymovie" align="middle" allowScriptAccess="sameDomain"
type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Mesmo sendo o método mais comum para inserir seus filmes Flash, ele tem alguns problemas:

  • Não há detecção de plug-in: assim, os usuários podem ver um conteúdo quebrado, ou mesmo nenhum conteúdo. E se não houver nenhum plug-in instalado, eles poderão ver, no IE, uma caixa de diálogo de “Instalação de controle ActiveX” – uma caixa que muitos usuários temem, devido aos diversos spywares e malwares – ou aquela estranha “peça de quebra-cabeça” nos navegadores baseados no Mozilla. Nenhum desses sistemas de instalação de plug-in são amigáveis aos usuários, e frequentemente não são auto-explicativos o suficiente para informar o que estão instalando.
  • Com as mudanças da disputa de patentes Eolas, os usuários têm que clicar primeiro no seu conteúdo em Flash para “ativá-lo”, antes de interagir com ele. Mais informação aqui.
  • Ele não é válido como HTML ou XHTML: a tag embed não existe em nenhuma versão do HTML ou do XHTML. No entanto, uma vez que diversos navegadores lidam com as tags object de modo diferente (ou não lidam, ou mesmo têm implementações cheias de bugs), a tag embed foi necessária como um mecanismo de contorno de falhas.

2. Apenas a tag object / Flash Satay


Este método ganhou popularidade depois de um artigo publicado, em 2002, no A List Apart. Aqui estão dois exemplos de inserção com apenas a tag object, e Flash Satay:

Apenas a tag object

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"
width="300" height="120">
<param name="movie" value="http://www.macromedia.com/shockwave/download/triggerpages_mmcom/flash.swf">
<param name="quality" value="high">
<param name="bgcolor" value="#FFFFFF">
<!--[if !IE]> <-->
<object data="http://www.macromedia.com/shockwave/download/triggerpages_mmcom/flash.swf"
width="300" height="120" type="application/x-shockwave-flash">
<param name="quality" value="high">
<param name="bgcolor" value="#FFFFFF">
<param name="pluginurl" value="http://www.macromedia.com/go/getflashplayer">
FALHA (o navegador deveria exibir algum conteudo em Flash, e naum isto).
</object>
<!--> <![endif]-->
</object>

Flash Satay

<object type="application/x-shockwave-flash
data="c.swf?path=movie.swf"
width="400" height="300">
<param name="movie"
value="c.swf?path=movie.swf" />
<img src="noflash.gif"
width="200" height="100" alt="" />
</object>

  • Problemas de acessibilidade: usando Flash Satay, alguns leitores de tela (como o JAWS) vão ignorar seu conteúdo em Flash.
  • Com as mudanças na disputa de patentes Eolas, os usuários têm que, primeiro, clicar no seu conteúdo em Flash para “ativá-lo” antes de começar a interagir com ele. Mais informações aqui.
  • Não existe detecção de plug-in (como no método anterior): sem essa detecção, os usuários podem ver conteúdo quebrado, ou nenhum conteúdo. Quando o Flash player encontra um filme Flash inserido em uma página, ele tentará executá-lo independente da sua versão. Assim, se você tiver o Flash player 6 instalado e um filme do Flash 7 for encontrado, seu plug-in tentará executá-lo, possivelmente causando comportamentos estranhos.
  • Alguns métodos do Flash satay não fazem o stream do filme Flash para o player: então este método pode exigir outros arquivos swf “recipientes”, onde o seu filme seja carregado. Isso torna a passagem de variáveis via Flashvars um incômodo, e também um tormento para manter o conteúdo em Flash, uma vez que existirão duas vezes mais arquivos swf espalhando-se pelo seu servidor web.
  • Versões antigas do Safari ignoram as tags “params”: o Safari completamente ignorava a tag param até a sua versão 2.0 (no Tiger), ou 1.3 (no Panther) e possivelmente 1.2.8 (pré Panther). Assim, se você fizesse configurações usando essas tags (como Flashvars, align, salign, etc.) o Safari não as reconheceria.

3. Detecção: o método do pequeno filme Flash na homepage


Neste método, coloca-se um único filme Flash na homepage do seu website, responsável por checar a variável $version no Flash player e redirecionar o usuário tanto para o conteúdo em Flash dentro do site, ou para uma página de atualização.

Os problemas com esse método incluem:

  • Não existe detecção nas páginas internas: se o usuário acessar a página por uma URL interna (se ele receber o link de um amigo, ou através de mecanismos de busca, por exemplo), esse usuário vai escapar da detecção feita somente na homepage.
  • Com as mudanças na disputa de patentes Eolas, os usuários terão que, primeiro, clicar no conteúdo em Flash para “ativá-lo” antes de interagir com ele. Mais informações aqui.
  • Não é HTML ou XHTML válido: mais uma vez, a tag embed usada para colocar os filmes Flash nos seus documentos HTML não é válida.
  • Fere a sua classificação nos mecanismos de busca: uma vez que você só usa a sua homepage como uma página vazia, que só possui uma detecção de Flash. Quando as pessoas procurarem seu site no Google ou outros mecanismos de busca, muitas vezes o texto de descrição será apenas algo como “Detectando Flash Player”, ou mesmo nenhuma descrição. Isso é uma gigantesca perda de valor do espaço que poderia ser usado para a promoção da sua companhia ou produto. Frequentemente os desenvolvedores não incluem sequer um link para outro conteúdo no site (uma vez que o filme Flash teria os links), assim o resto do site não será indexado também.

4. O Macromedia Flash Player Detection Kit


A Macromedia fez um excelente trabalho com o novo kit de detecção do Flash 8 – mas que não é excelente o bastante. Ele contém dois diferentes modos de detecção do plug-in do Flash:

  1. O clássico “pequeno filme Flash na homepage” (veja acima).
  2. Javascript: sim, isso mesmo, o Flash agora inclui um modelo de detecção de plug-in em Javascript. Infelizmente, ele de fato não é muito amigável ao usuário, misturando Javascript, VBscript e todo o seu HTML em uma só página. Isso tem muitas das desvantagens já citadas, e não facilita a sua vida de desenvolvedor Flash/HTML. E esse método também não valida como XHTML ou HTML (se você se preocupa com esse tipo de coisa).

Eu fiz uma análise mais profunda no kit de detecção da Macromedia, e coloquei o resultado aqui.

5. Usar Javascript cru para detectar e inserir seus filmes


É difícil criticar este método, uma vez que ele normalmente varia de site para site. No entanto, a maioria dos esquemas de detecção de Flash via Javascript que eu encontrei geralmente sofrem dos mesmos problemas:

  • A detecção do plug-in não é confiável: muitas vezes ela somente funciona com as versões atuais do Flash player, e precisa ser atualizada manualmente à medida que novas versões do plug-in forem lançadas.
  • Adiciona mais código à página: tornando mais difícil atualizar ou mudar seu conteúdo. Esse método também dificulta aos designers ou outras pessoas que estejam trabalhando nas suas páginas mudar ou adicionar filmes Flash.
  • Uma solução excessivamente complicada: muitos scripts de inserção de Flash podem se tornar grandes arquivos, ou serem demasiadamente complicados. O SWFObject foi projetado para ser simples e pequeno.

FAQ


P. O que é a “Atualização de Conteúdo Ativo” do Internet Explorer que eu ouvi falar, e o SWFObject corrige isso?
R. A resposta mais curta é sim, o SWFObject corrige esse problema da nova atualização do IE. Você pode saber mais sobre esse assunto aqui.

P. O que faz meu conteúdo alternativo piscar rapidinho na tela antes do meu conteúdo em Flash ser carregado? (apenas acontece no IE e no Windows).
R. Isso parece estar relacionado ao bug FOUC. E pode ser corrigido adicionando-se uma tag link no cabeçalho do seu documento para todas as folhas de estilo.

P. Eu posso usar o SWFObject para inserir mais de um swf em uma página HTML?
R. Sim. Basta fornecer um único ID para cada swf e cada div recipiente (ou outro elemento HTML que seja usado para isso).

P. Como eu faço o SWFObject funcionar no Netscape 4.x?
R. Este comentário tem um código de exemplo que você pode usar para fazer o SWFObject funcionar no Netscape 4.x.

P. Dá pra usar o SWFObject no meu blog?
R. Sim, existem plug-ins para o Wordpress e para o Textpattern aqui.

P. Dá pra usar o SWFObject com o Dreamweaver ou o Golive?
R. Existe uma extensão para o Dreamweaver disponível na CommunityMX. Ainda não existe extensão para o Golive, mas se você quiser fazer uma, eu ficarei satisfeito em colocar um link nesta página. Claro que você pode usar o script SWFObject sem uma extensão, mas ela torna o trabalho bem mais fácil.

P. Esta página está disponível em outros idiomas?
R. O texto original está disponível aqui (em inglês). Aqui existe uma tradução para o francês de partes desta página, uma tradução em sueco, italiano, alemão, espanhol, polonês (parcial), japonês, e aqui tem uma em finlandês. Eu ficarei feliz em postar um link aqui para quem quiser traduzir esta página em outros idiomas.

P. Existe um modelo de publicação que eu possa usar com o Flash?
R. Sim. Você pode baixar um do Fluid Flash Blog.

P. Quem usa o SWFObject/FlashObject?
R. Websites como o The Library of Congress, Adobe.com (uma versão levemente personalizada), Amazon.com, Windows.com, YouTube.com, skype.com, Snapple.com, ele está incluído no Adobe Photoshop (nas Flash web photo galleries) e milhares de outros. Colin Moock também sugeriu o SWFObject como alternativa ao Macromedia Detection Kit.

Ainda tem problemas? Tente ler os posts passados sobre o SWFObjects [1, 2, 3] neste blog (especialmente os comentários). Muitas questões comuns foram solucionadas ali.

Agradecimentos

Toby Boudreaux contribuiu com muitos conselhos, ajudou-me a tornar o código do SWFObject muito mais limpo e organizado ao mesmo tempo.