Nesse sentido, começamos uma série de artigos que nos detalharão alguns dos pontos mais interessantes que nos oferecem estas bibliotecas, começando nesta ocasião com uma introdução ao método Modernizr.load(), um gestor condicional de carregamento de bibliotecas Javascript e CSS.
Modernizr.load() está baseado em algumas bibliotecas chamadas yepnope.js que servem basicamente para carregar bibliotecas apenas quando os usuários as necessitam. Trata-se de um simples método que permite avaliar uma condição e dizer que bibliotecas carregar quando se cumpra e quais quando não.
As condições podem ser as propriedades que nos oferece Modernizr, de modo que carreguemos determinadas bibliotecas somente nos casos em que se necessitem. Por exemplo, pensemos que estamos fazendo uma página baseada no API Local Storage do HTML5. Com Modernizr podemos saber se o navegador do usuário oferece suporte a esse API, mediante a propriedade:
Quando em CriarWeb.com publicamos a apresentação inicial de Modernizr falamos dos Polyfills e explicamos que existiam bibliotecas para implementar quase todas as características do HTML5 em navegadores que não as suportavam de maneira nativa. Essas bibliotecas são os mencionados Polyfills e as podemos carregar de maneira condicional por meio de Modernizr.load().
Voltando ao exemplo do Local Storage, com Modernizr.load() podemos indicar aos navegadores que não suportem esse API que carreguem o Polyfill Storage, de modo que se possa utilizar essa característica do HTML 5 neles também.
Modernizr.load({
test: Modernizr.localstorage,
yep : 'existe_suporte_nativo.js',
nope: ['storage-polyfill.js', 'estilos-polyfill.css']
});
No código anterior podemos ver a chamada ao método load. Nela indicamos várias propriedades em notação de objeto:
Carregamento de bibliotecas para os casos positivos e negativos:
Também podemos especificar os arquivos Javascript ou CSS que queremos carregar quando se cumpra determinada avaliação e quando não se cumpra. Para tanto, simplesmente criamos outra propriedade no parâmetro passado a load(), chamada "both".
Modernizr.load({
test: Modernizr.multiplebgs && Modernizr.opacity,
nope: 'polyfills-css.js',
both: 'outras-coisas.js'
});
Neste caso serão avaliados se o navegador dispõe de suporte para múltiplos fundos com CSS3 e para as propriedades de opacidade. Em caso negativo se carregaria a biblioteca "polyfills-css,js" e tanto em caso positivo como no negativo (ou seja, em todos os navegadores) se carregaria a biblioteca "outras-coisas.js".
Fazer coisas depois do carregamento das bibliotecas:
Em algumas ocasiões queremos fazer algum tipo de ação, mas não queremos executá-la até não terem sido carregadas determinadas bibliotecas. Para isso, pode ser implementada uma função na propriedade complete, que só será executada quando as bibliotecas tenham sido carregadas.
Modernizr.load({
test: Modernizr.geolocation,
yep : 'geo-extras.js',
nope: 'geo-polyfill.js',
both: 'minhageolocalizacao.js',
complete: function(){
inicializar-geolocalizacao();
}
});
Neste caso se avalia se existe suporte ao API de geolocalização. Em caso positivo se carregam uns scripts ('geo-extras.js'), em caso negativo outros ('geo-polyfill.js') e para ambos casos se carrega outra biblioteca ('minhageolocalizacao.js'). O interessante neste exemplo é o método seguinte, baixo o nome de complete, onde se ha atribuído uma função que será executada só depois de haver carregado todas as bibliotecas que corresponda em cada caso. Nessa função podemos colocar código que necessite dessas bibliotecas com total segurança, já que saberemos seguramente que seu carregamento terá sido realizado anteriormente a sua execução da função complete.
Carregamento no condicional de bibliotecas
Com Modernizr.load() também podemos carregar bibliotecas de maneira incondicional, ou seja, sem avaliar previamente nenhuma condição. Para tanto utilizamos a propriedade load. Agora vemos um método copiado diretamente do tutorial de Modernizr.load() que está na documentação destas bibliotecas.
Eu o copiei porque me parece um caso excelente de uso desta funcionalidade. Trata-se de um script que se traz por CDN à biblioteca jQuery mas que, se houve algum problema com tal biblioteca, carrega jQuery diretamente de uma cópia do framework em nosso servidor local.
Modernizr.load({
load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.js',
complete: function () {
if ( !window.jQuery ) {
Modernizr.load('js/jquery-1.6.3.min.js');
}
}
});
Neste exemplo se carrega jQuery a partir do CDN de Google APIs. Utilizamos a propriedade "load", logo não existe nenhuma avaliação, senão que simplesmente se carrega essa biblioteca independentemente do navegador do usuário. Em seguida se utiliza complete para especificar uma função a ser a executada quando se termina o carregamento das bibliotecas. Nessa função se avalia !window.jQuery. Se jQuery não tivesse sido carregado, essa avaliação nos levaria ao carregamento do framework diretamente de uma rota a partir de nosso próprio servidor, utilizando de novo Modernizr.load().
Carregamento de vários pacotes de bibliotecas de maneira sequencial:
Por último vamos mostrar como realizar vários blocos de carregamento de bibliotecas dentro de uma única chamada a modernizr.load(), o que nos servirá quando queiramos carregar condicionalmente diversos conjuntos de bibliotecas dependendo de várias avaliações independentes. Todos esses blocos serão indicados em um array e serão executados um atrás do outro, e por isso até que não sejam carregadas as bibliotecas do primeiro bloco, não se passará ao seguinte.
Modernizr.load([
//Primeiro bloco
{
test : Modernizr.fontface,
nope : ['fontes-css.js', 'outros-estilos.css']
},
//Segundo bloco
{
test : Modernizr.audio,
nope : 'suporte-audio.js',
both : 'meu_fio_musical.js',
complete : function () {
iniciarMusica();
}
},
//terceiro bloco
'script-estatisticas.js'
]);
Neste exemplo temos três blocos.
Cabe destacar também, segundo comentado na documentação, que este modo de carregamento sequencial de bibliotecas, apesar de ter que esperar o completo descarregamento de um bloco antes de começar o carregamento do seguinte, não suporá uma redução da velocidade do site com respeito a se todas as bibliotecas foram descarregadas em paralelo. Inclusive em determinadas ocasiões dizem que poderia aumentar a velocidade.
O que está claro é que, graças a Modernizr, podemos facilmente discriminar entre navegadores e carregar somente aquelas bibliotecas que nosso navegador necessite, em vez de carregá-las todas e depois ver se realmente eram necessárias. Sem dúvida poderíamos fazer nossas próprias validações para averiguar se são necessárias e em seguida carregá-las por meio de nossos próprios scripts, mas dificilmente vamos poder realizar as coisas por nós mesmos mais rápido e melhor do que propõe Modernizr.load().
No artigo seguinte apresentaremos um exemplo completo de carregamento de um pollyfill para compatibilidade com Canvas del HTML 5, condicionalmente por meio de Modernizr.load(), de modo que só se invoque quando o navegador não disponha de suporte nativo para canvas.