A configuração de um src de imagem como URL de dados deve estar disponível imediatamente?
Considere o seguinte código JavaScript (frágil):
var img = new Image;
img.src = "data:image/png;base64,..."; // Assume valid data
// Danger(?) Attempting to use image immediately after setting src
console.log( img.width, img.height );
someCanvasContext.drawImage( img, 0, 0 );
// Danger(?) Setting onload after setting src
img.onload = function(){ console.log('I ran!'); };
As questões)
A largura e a altura da imagem devem estar corretas imediatamente?O desenho da tela deve funcionar imediatamente?Oonload
retorno de chamada (definido após a alteração do src) ser chamado?Testes experimentais
Eu criei umpágina de teste simples com código semelhante. No Safari, meus primeiros testes, abrindo a página HTML localmente (file:///
url) e carregá-lo no meu servidor, mostrou tudo funcionando: a altura e a largura estão corretas, o desenho da tela funciona,e aonload
também dispara.
No Firefox v3.6 (OS X), carregar a página após iniciar o navegador mostra que a altura / largura não está correta imediatamente após a configuração,drawImage()
falha. (Oonload
no entanto, o manipulador é acionado.) Carregar a página novamente mostra a largura / altura correta imediatamente após a configuração edrawImage()
trabalhando. Parece que o Firefox armazena em cache o conteúdo do URL de dados como uma imagem e o disponibiliza imediatamente quando usado na mesma sessão.
No Chrome v8 (OS X), vejo os mesmos resultados que no Firefox: a imagem não está disponível imediatamente, mas leva algum tempo para 'carregar' de forma assíncrona a partir do URL de dados.
Além da prova experimental do que os navegadores acima funcionam ou não, eu adoraria links para especificações sobre como isso deve se comportar. Até agora, o meu Google-fu não está à altura da tarefa.
Jogando com segurança
Para aqueles que não entendem por que os itens acima podem ser perigosos, saiba que você deve usar imagens como esta para garantir:
// First create/find the image
var img = new Image;
// Then, set the onload handler
img.onload = function(){
// Use the for-sure-loaded img here
};
// THEN, set the src
img.src = '...';