Image Image Image Image Image
Scroll to Top

Topo

jquery

14

abr
2012

Sem Comentários

Em Blog

Por Allison

jQuery Mobile 1.1.0 é anunciado

Em 14, abr 2012 | Sem Comentários | Em Blog | Por Allison

Fonte: IMasters

A equipe de desenvolvimento do jQuery Mobile anunciou a versão 1.1.0 do framework web.

Entre as melhorias, os destaques são correção para barras de ferramentas, mudança na transição de páginas animadas e no carregador Ajax, formulário de design de elemento refinado e configuração de funcionalidade, e documentação aprimorada.

Para tornar a atualização da versão 1.0 para a 1.1 suave, os desenvolvedores lançaram a ferramenta ThemeRoller Mobile que suporta ambas as versões e torna fácil a migração de temas da 1.0 para a 1.1.

Além disso, a nova versão traz suporte para jQuery 1.7.1, para o módulo AMD.

A lista de novas funcionalidades e de correções de bugs é extensa, e pode ser vista em detalhes no anúncio de lançamento.

O jQuery Mobile 1.1.0 está disponível para download aqui.

Tags | , ,

13

abr
2012

Sem Comentários

Em Blog
Código

Por Allison

JavaScript: aviso de dados não salvos

Em 13, abr 2012 | Sem Comentários | Em Blog, Código | Por Allison

Fonte: Igor Escobar/IMasters

Sabe quando você está escrevendo um e-mail e, quando tenta sair da tela, o browser te dá um aviso, comunicando a possível perda de dados? Pois é sobre isso que vamos falar! O Gmail faz isso e o Rally também, mas muita gente ainda não sabe como isso é feito de fato.

Esse tipo de recurso é muito interessante e pode evitar muita dor de cabeça para quem estiver utilizando o seu sistema. No meu caso, esse recurso foi aplicado a um CMS. A finalidade da implantação era para que os jornalistas fossem avisados quando algum dado no formulário fosse alterado, porém, se o usuário intencionalmente (ou não) tentasse mudar de página, esse dado seria perdido. Tratando-se de um CMS focado para jornalistas, no qual o conteúdo digitado é extremamente importante, todos os recursos que forem desenvolvidos para evitar a perda de conteúdo são extremamente bem-vindos.

onBeforeUnload Event

O evento onbeforeunload não tem uma finalidade exclusiva para ele. É um evento como outro qualquer, que ele é invocado sempre que o usuário tenta sair da página atual, mas, quando ele não está setado, simplesmente nada acontece. O evento responsável por pedir para que o usuário confirme ou não a mudança de página é o onbeforeunload. Sempre que ele for setado, você vai ver um confirm dialog igual ao da imagem abaixo:

O problema

Se fosse só setar o efeito e ele fizesse todo o resto seria fácil, não é? Bom, mas não é bem assim. Temos que fazer com que um script peça a intervenção do usuário nas seguinte situações:

  1. Ao fechar aba/navegador;
  2. Ao clicar em qualquer outro link, senão o submit do formulário;
  3. O alerta deve aparecer somente se algo for alterado no formulário.

A solução

$(function(){
  var formObject = $('.new_materia, .edit_materia');
  formObject.data('original_serialized_form', formObject.serialize());
 
  $(':submit').click(function() {
    window.onbeforeunload = null;
  });
 
  window.onbeforeunload = function() {
    if (formObject.data('original_serialized_form') !== formObject.serialize()) {
      return "As mudanças deste formulário não foram salvas. Saindo desta página, todas as mudanças serão perdidas.";
    }
  };
});

Como funciona?

  1. Utilizei o $.data() do jQuery porque eu não gosto de utilizar o var para declarar variáveis globais;
  2. Utilizei o $.serialize() do jQuery para serializar o formulário para comparar o estado do formulário no futuro. E foi a forma mais inteligente que encontrei para identificar se algo realmente foi mudado no formulário;
  3. Por default, eu seto o evento onbeforeunload e dentro dele eu verifico se algo foi mudado no formulário;
  4. O único caso em que eu tenho que remover o evento onbeforeunload é quando existe a intenção de salvar o dado, no caso utilizei o :submit com evento $.click() para remover o evento e cancelar o alerta, caso haja a intenção de salvar o formulário.

Tags | , , ,

10

abr
2012

Sem Comentários

Em Blog

Por Allison

Como criar um aviso de dados não salvos

Em 10, abr 2012 | Sem Comentários | Em Blog | Por Allison

Sabe quando você está escrevendo um e-mail e tenta sair de tela, o browser te da um aviso, comunicando a possível perda de dados? Pois é sobre isso que vamos falar. O Gmail e o Rally fazem isso, mas muita gente ainda não sabe como isso é feito de fato.

Este recurso é muito interessante e pode evitar muita dor de cabeça por parte da pessoa que estiver utilizando o seu sistema. No meu caso, este recurso foi aplicado a um CMS. A finalidade da implantação era para que os jornalistas fossem avisados quando algum dado no formulário fosse alterado, e que se o usuário intencionalmente (ou não) tentasse mudar de página, o dado seria perdido. Se tratando de um CMS focado para jornalistas, no qual o conteúdo digitado é extremamente importante, todos recurso que for desenvolvido para evitar perda de conteúdo é extremamente bem-vindo.

onBeforeUnload Event

O evento onbeforeunload não tem uma finalidade exclusiva para ele. É um evento como outro qualquer, que é invocado sempre que o usuário tenta sair da página atual, mas quando ele não está setado, simplesmente nada acontece. O evento responsável por pedir para que o usuário confirme ou não a mudança de pagina é o evento onbeforeunload. Sempre que ele é setado, você vai ver um confirm dialog, igual o da imagem abaixo.

O problema

Se fosse só setar o efeito e ele fizesse todo o resto, seria fácil, não? Mas não é assim. Temos que fazer um script que peça a intervenção do usuário nas seguinte situações:

Ao fechar aba/navegador;

Ao clicar em qualquer outro link, senão o submit do formulário;

O alerta deve aparecer somente se algo for alterado no formulário.

A Solução

$(function(){
  var formObject = $('.new_materia, .edit_materia');
  formObject.data('original_serialized_form', formObject.serialize());

  $(':submit').click(function() {
    window.onbeforeunload = null;
  });

  window.onbeforeunload = function() {
    if (formObject.data('original_serialized_form') !== formObject.serialize()) {
      return "As mudanças deste formulário não foram salvas. Saindo desta página, todas as mudanças serão perdidas.";
    }
  };
});

Como funciona?

Utilizei o $.data() do jQuery porque eu não gosto do var para declarar variáveis globais;

Utilizei o $.serialize() do jQuery para serializar o formulário para comparar o estado do formulário no futuro. E foi a forma mais inteligente que encontrei para identificar se algo realmente foi mudado;

Por default, eu seto o evento onbeforeunload e dentro dele eu verifico se algo foi mudado no formulário;

O único caso em que eu tenho que remover o evento onbeforeunload é quando existe a intenção de salvar o dado. Aí eu utilizei o :submit com evento $.click() para remover o evento e cancelar o alerta, caso houvesse a intenção de salvar o formulário.

Bom, é isso!

Tags | , , , ,

10

abr
2012

Sem Comentários

Em Blog
JavaScript

Por Allison

Anunciado o lançamento da jQuery Foundation

Em 10, abr 2012 | Sem Comentários | Em Blog, JavaScript | Por Allison

Fonte: IMasters

Com informações de Linux-Under.org

O Conselho jQuery e o Software Freedom Conservancy anunciaram ontem, dia 07/03, o lançamento da jQuery Foundation. A nova organização independente irá gerenciar todos os assuntos relacionados a jQuery, incluindo os seus projetos.

O Presidente da Fundação será Dave Methvin, que já se pronunciou a respeito e disse que o sistema é a mais popular biblioteca JavaScript. “A criação de uma organização autônoma, será o próximo passo para garantir seu desenvolvimento futuro e beneficiar a todos que utilizam o jQuery”, afirmou.

Methvin também afirmou, que a Fundação anunciará várias iniciativas e conferências, que estão planejadas para serem realizadas em breve. A Fundação jQuery é uma associação comercial sem fins lucrativos, que se dedica a apoiar os diversos projetos da plataforma de mesmo nome (Core, UI e Mobile), fornecendo uma importante documentação e suporte, e ajudando a construir a comunidade jQuery, de forma sólida e com credibilidade.

Tags | , ,

07

abr
2012

Sem Comentários

Em Blog
Código

Por Allison

Como criar máscaras com jQuery Mask Plugin

Em 07, abr 2012 | Sem Comentários | Em Blog, Código | Por Allison

Fonte: Igor Escobar/IMasters

Neste mês ocorreu o lançamento oficial da versão 0.4.3 do meu plugin jQuery Mask Plugin. Como nunca escrevi um artigo a respeito, hoje vou ensinar a vocês como utilizá-lo e vou falar de algumas features interessantes do plugin.

Baixando o código

wget https://github.com/igorescobar/jQuery-Mask-Plugin/blob/master/jquery.mask.min.js

A única coisa que vocês precisam fazer é incluir o plugin entre as tags do seu documento e pronto! O plugin está pronto para vocês utilizarem.

A sintaxe

A sintaxe do jQuery Mask Plugin é bem simples. Primeiro, você passa o seletor, seguido de .mask e como parametro você vai passar a máscara que você quer que o campo tenha. Exemplo:

$(document).ready(function(){
$('.date').mask('00/00/0000');
});

Neste exemplo, todos os input fields que possuem a classe “.date” terão a máscara aplicada. No jQuery Mask Plugin você não tem máscaras pré-estabelecidas e pode escolher como você quiser. No site do projeto é possível ver o jQuery Mask Plugin funcionando e mais alguns outros exemplos, como os a seguir:

$(document).ready(function(){
$('.date').mask('11/11/1111');
$('.time').mask('00:00:00');
$('.date_time').mask('99/99/9999 00:00:00');
$('.cep').mask('99999-999');
$('.phone').mask('9999-9999');
$('.phone_with_ddd').mask('(99) 9999-9999');
$('.phone_us').mask('(999) 999-9999');
$('.mixed').mask('AAA 000-S0S');
});

Veja que eu posso definir o tipo de dado que o usuário pode imputar a cada dígito. Nesta máscara, por exemplo:

$('.mixed').mask('AAA 000-S0S');

O usuário poderá digitar uma sequência de três caracteres alpha números, seguido de espaço, seguido de três caracteres números, seguido de traço, seguido de um caractere do tipo string, seguido de um caractere do tipo inteiro e seguido de um caractere do tipo string. Interessante, não?

Vocês podem definir a máscara como quiserem e também podem definir o tipo de dado que pode ser inputado em cada dígito da máscara.

Features

  • Validação de tipo de dado inputado;
  • Máscaras flexíveis;
  • Live Events para aplicações Ajax;
  • Maxlength automático.

Mais sobre o jQuery Mask Plugin

  1. jQuery Mask Plugin no Github
  2. Página de demonstração
  3. Versão Beta do jQuery Mask Plugin
  4. Todas as versões do jQuery Mask Plugin

Tags | , ,

24

mar
2012

Sem Comentários

Em Blog

Por Allison

Versão 1.7.2 do jQuery é liberada

Em 24, mar 2012 | Sem Comentários | Em Blog | Por Allison

Fonte: IMasters

A equipe de desenvolvimento do jQuery liberou hoje a versão 1.7.2 da biblioteca JavaScript. Segundo os desenvolvedores, apenas uma pequena mudança foi realizada em relação ao release candidate.

O código do jQuery CDN já está disponível nos seguintes endereços:

Aqueles que estiverem usando jQuery Mobile devem utilizar o jQuery 1.7.2 apenas com o jQuery Mobile 1.1. Para versões anteriores da versão móvel da biblioteca, é recomendável ficar com jQuery core 1.7.1 ou anteriores.

Os desenvolvedores pedem que os usuários utilizem o bug tracker para reportar bugs.

Mais detalhes sobre o jQuery 1.7.2 estão disponíveis no anúncio de lançamento.

Tags | , ,

13

fev
2012

Sem Comentários

Em Blog
Wordpress

Por Allison

Border-Radius em todos os navegadores

Em 13, fev 2012 | Sem Comentários | Em Blog, Wordpress | Por Allison

Outra coisa que geralmente me deixa furioso é ter que fazer border-radius usando sobreposição de imagens, e criar uma infinidade de codigo css e javascript para conseguir executar esta função tão querida dos nossos colegas designers.

Então o ultimo site que recebi solicitando a propriedade de border-radius nas imagens começei uma odisseia testando varios scripts que prometiam fazer o indicado em todos os navegadores, inclusive o famigerado IE. Demorei algum tempo de pesquisa, mas finalmente encontrei o javascript que faz o que eu preciso.

Corner.js é o nome da aplicação que eu precisava. Funciona de uma maneira bem simples, basta vc colocar algumas descrições a mais em uma classe indicando o que vc quer que faça e o resto é por conta do script. Como eu uso wordpress, tive que fazer um pequeno ajuste via jquery para que a classe fosse adicionada automaticamente em toda a imagem nova publicada.

Depois de feito download do script, coloquei ele na pasta js/ que fica dentro na pasta do meu tema, algo assim wp-content/themes/meu-tema/js/. Depois inseri este codigo no arquivo functions.php

wp_enqueue_script('corner', get_bloginfo('template_url') . '/js/corner.js', array

Que é uma maneira elegante de chamar o javascript que vc precisa, sem colocar ele diretamente no arquivo header.php, ou algo do genero. Coloquei ele precisando do jquery pois vou precisar do jquery para colocar as classes necessarias.

No arquivo header.php antes do escrevi o seguinte codigo:

<script type="text/javascript">
* <![CDATA[ */
    jQuery(document).ready(function(){
        jQuery("img").addClass("corner iradius15");
    });
/* ]]> */
</script>

Isto faz com que todas as imagens do site tenham border-radius 15px.

Testei em todos os navegadores quanto eu consegui, e funcionou em todos.

Tags | , , , , ,

01

fev
2012

Sem Comentários

Em Blog

Por Allison

jQ.Mobi: um jQuery reescrito e otimizado para dispositivos móveis

Em 01, fev 2012 | Sem Comentários | Em Blog | Por Allison

Fonte: Postado por Abel Avram/traduzido por Eder Ignatowicz/InfoQ

A appMobi lançou o jQ.Mobi, uma versão reescrita e gratuita do jQuery, que compete com o jQuery Mobile no mercado de desenvolvimento web para dispositivos móveis.

O jQ.Mobi é otimizado para HTML5 e dispositivos móveis. Comparado ao jQuery, é mais leve (3KB contra 35KB), três vezes mais rápida em dispositivos Android e 2.2 vezes mais performática no iOS, tudo isso de acordo com testes JSPerf. A sintaxe de programação do jQ.Mobi é idêntica à do jQuery, assim como o desenvolvimento de plugins. O jQ.Mobi contém somente um subconjunto considerado essencial da API do jQuery (segundo a appMobi) e tem por objetivo prover uma experiência idêntica ao usuário, em ambos iOS e Android.

O jQ.Mobi é formado por três componentes:

  • Uma biblioteca de consultas;
  • jQ.Ui: uma biblioteca de interface de usuário para browsers WebKit;
  • jQ.Plugin: suporte a plugins desenvolvidos para browsers WebKit.

Por que alguém criaria um novo framework JavaScript baseado no JQuery dois meses após o lançamento do jQuery Mobile 1.0? A appMobi explica que as raízes do jQuery são baseadas em browsers desktop e como resultado, a versão mobile do framework não seria otimizada e não proporciona uma boa experiência para usuários de dispositivos móveis, especialmente no Android.

Com relação ao jQuery Mobile, Todd Parker, líder do projeto, reconheceu problemas com o jQuery Mobile. A equipe do jQuery anunciou uma versão de correção (1.0.1) em que resolve um grande número de bugs e acrescenta componentes visuais, além de antecipar funcionalidades para as próximas versões.

Uma versão de demonstração foi criada para ilustrar as funcionalidades da biblioteca. Mais detalhes sobre a evolução do projeto podem ser acompanhados no blog do jQ.Mobi.

Tags | , , , , ,

29

jan
2012

Sem Comentários

Em Blog

Por Allison

Versão 1.0.1 do jQuery Mobile é lançada

Em 29, jan 2012 | Sem Comentários | Em Blog | Por Allison

Fonte: IMasters

O jQuery Mobile 1.0.1 foi lançado e traz uma longa lista de correções, alguns ajustes de desempenho e pequenas melhorias.

Segundo os desenvolvedores, a plataforma Samsung bada e seu navegador Dolphin agora são oficialmente suportados.

Além disso, eles começaram a testar o jQuery Mobile no UC Browser e no Android, e afirmaram que tudo funcionou bem. O UCweb é o browser móvel mais popular da China, com 65% de marketshare do país.

O jQuery Mobile tem suporte para a maioria das plataformas de desktops, smartphones, tablets e e-readers. Em adição, feature phones e browsers mais antigos também são suportados.

Uma lista completa das plataformas com suporte e o changelog estão disponíveis no anúncio oficial de lançamento, de onde também é possível fazer o download do jQuery Mobile 1.0.1.

Tags | , ,

23

jan
2012

Sem Comentários

Em Blog
HTML

Por Allison

HTML5 e JQuery – O elemento Slider

Em 23, jan 2012 | Sem Comentários | Em Blog, HTML | Por Allison

Fonte: Sara/PlusCoding

Como nós sabemos com o HTML5 saíram imensos input types que pudemos usar com os nossos formulários para dar uma melhor visita aos utilizadores, um deste elementos é o slider o qual vou explicar como usar neste tutorial.

O slider atualmente só é suportado pelo opera e google chrome portanto este tutorial é meramente informativo e durante uns tempos seria melhor para os vossos utilizadores usarem a Jquery UI para atingirem este efeito.

O html para termos um slider é muito simples é só:

<input id="slider" type="range" min="0" max="100" step="5" value="50" />


Passando a explicar, o input type de slider pode levar estes quatro atributos:

Min é o mínimo do slider, neste caso é 0 mas podem definir como quiserem.

Max é exactamente o contrário e neste caso pus 100 para o nosso slider ser de 0 a 100.

Step é quanto muda o valor quando mexemos no slider, neste caso o nosso slider quando é mexido muda de 5 em 5 valores, sendo impossível colocarmos por exemplo 91, pois este salta do 90 para o 95.

Value é com quanto o nosso slider começa de origem.

Depois colocamos um span para conseguirmos identificar no Jquery e mudar o seu valor de acordo com o valor do slider:

<input id="slider" type="range" min="0" max="100" step="5" value="50" />
<p>Valor actual:<span id="valor">50</span></p>

Agora vem o Jquery:

$('#slider').change(function(){
$('#valor').html(this.value);
});

O que este pequeno pedaço de JQuery faz é quando o elemento com o id de slider é mudado ele muda o html do span com o id de valor para que este fique igual ao value do slider.

Como podem ver com um pouco de JQuery e HTML5 podemos dar uma visita melhor aos nossos utilizadores, se quiserem ver a demo a funcionar podem ver abaixo e esperem mais dicas destas de como juntar o HTML5 e Jquery para fazer pequenos melhoramentos á visita de o utilizador.

(Usem apenas Chrome ou Opera para Visualizar a demo pois como disse acima são os únicos que suportam este elemento)

Tags | , , , ,

23

jan
2012

Sem Comentários

Em Blog

Por Allison

Como trabalhar com Comet Server usando Nginx e JQuery

Em 23, jan 2012 | Sem Comentários | Em Blog | Por Allison

Fonte: Rafael Cirolini/NeardHead

Pesquisei bastante por exemplos de jquery funcionando fazendo requisições de long polling, e finalmente encontrei um bom exemplo em Jamieisaacs Blog que demostra muito bem esta tecnica.

Basta criar o arquivo listem.html na pasta html dentro do seu nginx, ou na pasta root do site.

Como de costume, vou colocar o codigo e ir comentando.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Listen</title>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script>
        <script type="text/javascript">
        /* <![CDATA[ */
   google.load("jquery", "1.4.2"); /*carrega o jquery atraves da api js do google */
 
   function listen(last_modified, etag) {
       $.ajax({
       /* antes de enviar seta os cabeçalhos */
           'beforeSend': function(xhr) {
               xhr.setRequestHeader("If-None-Match", etag);
               xhr.setRequestHeader("If-Modified-Since", last_modified);
           },
           url: '/activity/?id=teste', /* url de push configurado no nginx */
           dataType: 'text',
           type: 'get',
           cache: 'false',
           success: function(data, textStatus, xhr) {
               /* pega os cabeçalhos recebidos pela conexão para utilizar na proxima requisição */
               etag = xhr.getResponseHeader('Etag');
               last_modified = xhr.getResponseHeader('Last-Modified');
 
               div = $('<div class="msg">').text(data);
               info = $('<div class="info">').text('Last-Modified: ' + last_modified + ' | Etag: ' + etag);
 
        /* escreve na div data as informações de retorno */
               $('#data').prepend(div);
               $('#data').prepend(info);
 
               /* faz uma nova requisição */
               listen(last_modified, etag);
           },
           error: function(xhr, textStatus, errorThrown) {
               $('#data').prepend(textStatus + ' | ' + errorThrown);
           }
       });
   };
 
   google.setOnLoadCallback(function() {
       /* Inicia o primeiro long poll. */
       /* O timeout é necessario para o navegador saber que a pagina terminou de carregar */
       setTimeout(function() {
           listen('', '');
       }, 500);
   });
        /* ]]> */
        </script>
        <style type="text/css">
            #data {
                margin: .5em;
            }
 
            #data .info {
                font-weight: bold;
                font-size: 14px;
            }
 
            #data .msg {
                white-space: pre;
                font-family: courier;
                font-size: 14px;
                margin-bottom: .5em;
                margin-left: .5em;
            }
        </style>
    </head>
    <body>
        <div id="data"></div>
    </body>
</html>

Agora segue o arquivo que faz o envio das msg no canal. O funcionamento é simples, quando clica no botão ele pega o valor do input e faz um POST na url de publicação e exibe o resultado.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>Send</title>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script>
        <script type="text/javascript">
        /* <![CDATA[ */
    google.load("jquery", "1.4.2");
 
    function showResult(status, response) {
        $('#result').html('<strong>status:</strong> ' + status +
        '<br /><strong>response:</strong><br />' + response);
    };
 
    google.setOnLoadCallback(function() {
        $('#pub').submit(function() {
            message = $('#message').val();
 
            /* Do not send empty message */
            if (message == '') {
                return false;
            }
 
            $.ajax({
                url: '/publish/?id=teste',
                data: message,
                dataType: 'text',
                type: 'post',
                success: function(responseText, textStatus, xhr) {
                    showResult(textStatus, responseText);
                },
                error: function(xhr, textStatus, errorThrown) {
                    showResult(textStatus, errorThrown);
                }
            });
            return false;
        });
    });
        /* ]]> */
        </script>
 
    </head>
    <body>
        <form id="pub" method="post" action="/publish/?id=teste"><input type="hidden" name="phpMyAdmin" value="8C%2CP2bFpgP9WryjAxnBRYbq8ub5" />
            <input type="text" class="message" name="message" id="message" />
            <input class="submit" type="submit" value="send" />
        </form>
        <div id="result"></div></div>
    </body>
</html>

Tags | , , ,

16

jan
2012

Sem Comentários

Em Blog
JavaScript

Por Allison

Como otimizar códigos jQuery e aumentar a performance do front-end

Em 16, jan 2012 | Sem Comentários | Em Blog, JavaScript | Por Allison

Este é um artigo traduzido do original Your JQuery: Now With 67% Less Suck, do blog 24 ways – e sofreu pequenas adaptações.

Fonte: DesenvolvimentoparaWeb

Otimizar códigos jQuery em um site significa aumentar sua performance. E, como qualquer desenvolvedor web deveria saber, os componentes e recursos do front-end são responsáveis por, pelo menos, 80% da performance de páginas web!

O jQuery, em relação a JavaScript “puro”, já é bem simples de se aprender e possui uma gama de recursos incrível! Entretanto, principalmente quem está começando e/ou ainda não entendeu bem a dinâmica da biblioteca, desconhece alguma dicas simples que, se aplicadas, garantem que o desempenho seja aumentado escrevendo menos código! É isso que vamos ver neste artigo e aprender como melhorar códigos jQuery para conseguir um desempenho melhor.

1. Otimização de seletores

Para começar, vejamos como é possível otimizar os seletores no jQuery, otimizando as consultas realizadas e aumentando a performance do código.

1.1. Velocidade de seletores

Muito do poder do jQuery vem de sua capacidade de selecionar elementos DOM e agir/interagir com eles através de seus selectors e, através deles, o jQuery provê uma tonelada de maneiras de escolher qual(is) elemento(s) em uma página se quer trabalhar. No entanto, um número surpreendente de desenvolvedores web não sabe que os seletores não são todos iguais e que é incrível a diferença de desempenho entre 2 seletores que, à primeira vista, parecem quase idênticos.

Como exemplo, vejamos 2 maneiras de selecionar todas as tags de parágrafo dentro de uma div com id específico:

$('#id p');

$('#id').find('p');

É surpreendente o fato de que a segunda maneira pode ser 2 vezes mais rápida!

Há muitas maneiras diferentes de selecionar elementos usando jQuery; estas podem ser (virtualmente) divididas em 5 diferentes métodos. Em ordem, do mais rápido para o mais lento, são:

  • $(‘#id’). Sem dúvidas, este é o selector mais rápido, já que mapeia diretamente o document.getElementbyId() nativo do JavaScript. Sempre que possível, os seletores descendentes devem ser feitos com um seletor de ID conjuntamente ao método .find(), que limita o escopo do que está sendo pesquisado (tal como no exemplo $(‘#id’).find(‘p’) anterior).
  • $(‘p’), $(‘input’), $(‘form’), […]. Selecionar elementos pelo nome da tag também é rápido, já que mapeia diretamente para o método nativo document.getElementsByTagname().
  • $(“.class”). Selecionar por nome de classes é um pouco mais custoso. Enquanto isso é executado muito bem por navegadores modernos, pode ser que uma lentidão seja causada em versões do IE baixo da 9. Por quê? Porque o IE9 foi a primeira versão do Internet Explorer a dar suporte para a função document.getElementsByClassName(), nativa do JavaScript. Para interpretar isso, browsers mais antigos têm de recorrer ao usos de artifícios bem mais custosos, que realmente afetam o desempenho do seletor.
  • $(‘[attribute=”value”]’). Não há nenhum método JavaScript nativo para este tipo seletor, então, a única maneira que pode realizar essa busca, é procurar por todo o DOM em busca de combinações que satisfaçam à condição do seletor. Navegadores modernos que suportam o método querySelectorAll() terão um desempenho melhor em certos casos, mas, em geral, este tipo de seletor é bastante lento.
  • $(‘:hidden’). Assim como o caso anterior, não existe um método JavaScript nativo para usar este tipo de seletor. Pseudo-seletores podem ser extremamente lentos, já que a consulta tem que ser executada em cada elemento da página. Novamente, navegadores modernos que suportam o método querySelectorAll() se saem ligeiramente melhores, mas tente evitar este tipo de seleção. Se realmente for necessário, é possível amenizar um pouco usando o .find(), como visto anteriormente. Por exemplo: $(‘#list’).find(‘:hidden’).

1.2. Encadeamento

Quase todos os métodos jQuery retornam um objeto jQuery. Isto significa que, quando um método é executado, seus resultados são retornados e é possível continuar a implementação de mais métodos em sequência, o que é conhecido como encadeamento ou chaining. Ao invés de escrever o mesmo seletor várias vezes, esta característica da biblioteca permite que várias ações possam ser executadas de uma vez.

Sem encadeamento:

$('#object').addClass('active');
$('#object').css('color','#F0F');
$('#object').height(300);

Com encadeamento:

$('#object').addClass('active').css('color','#F0F').height(300);

Isto tem um duplo efeito ao tornar seu código mais curto e mais rápido. Métodos encadeados são executados mais rapidamente do que vários métodos de um seletor em cache e, de ambos os jeitos, são muito mais rápidos que vários métodos através de seletores sem cache. Mas, esperem… “Seletor em cache”? O que é isso?

1.3. Seletores em cache

Outra maneira fácil de melhorar a performance do código jQuery – e que parece ser um mistério para a maioria dos desenvolvedores – é a ideia de fazer cache de seletores. Pense em quantas vezes você acaba escrevendo o mesmo seletor em seus códigos. Cada $(‘.element’) tem que varrer todo o DOM procurando por combinações o tempo todo, independentemente se este seletor tenha sido executado antes. Executando a seleção uma vez e depois guardando o(s) resultado(s) em uma variável, significa que a busca no DOM tem que ser feita apenas uma única vez. Uma vez que os resultados de um seletor tem sido armazenada em cache, é possível fazer qualquer coisa com eles.

Primeiro, executa-se o seletor desejado (como exemplo, pegar todos os li dentro de uma ul de id “blocks”):

var blocks = $('#blocks').find('li');

Agora, é possível usar a variável blocks em qualquer lugar que se queira, sem ter que percorrer todo o DOM novamente em cada vez:

$('#hideBlocks').click(function(){
    blocks.fadeOut();
});
$('#showBlocks').click(function(){
    blocks.fadeIn();
});

Portanto, fica essa preciosa dica: qualquer seletor que é executado mais de uma vez deve ser armazenado em cache! Veja este teste no jsperf que mostra o quão mais rápido e eficiente é um seletor cacheado em detrimento a um não cacheado.

2. Delegação de Evento ou Event Delegation

Event listeners consomem memória. Em sites e aplicações complexos não é incomum ter um monte de event listeners implementados e, felizmente, jQuery fornece métodos realmente fáceis para umaa gestão eficiente event listeners através da delegação.

Num exemplo extremo, imagine uma situação em que uma tabela 10×10 precisa ter um event listener em cada uma de suas células para que, quando ocorrer um clique em alguma delas, seja adiciona ou removida uma classe que define a cor de fundo da respectiva célula. Uma maneira comum de implementar isso (e algo bastante comum de ser visto em códigos jQuery) é:

$('table').find('td').click(function() {
    $(this).toggleClass('active');
});

O jQuery, a partir de sua versão 1.7, passou a oferecer um novo método de escuta de eventos: .on(). Ele age como um utilitário que envolve todos os event listeners anteriores do jQuery em um único e conveniente método e a forma que ele é implementado determina como ele se comporta. Ao reescrever o exemplo acima usando .on(), tem-se o seguinte:

$('table').find('td').on('click',function() {
    $(this).toggleClass('active');
});

Bastante simples, certo? Mas o problema aqui é que, mesmo com a mudança, o código ainda conta com um event listener para cada célula da tabela… Uma maneira muito melhor de fazer isso funcionar é criar um único event listener para monitorar os eventos na própria tabela! Uma vez que a maioria dos eventos faz bubbling (vai percorrendo seus ancestrais em sequência) na árvore do DOM, é possível vincular um único listener para um elemento (neste caso, table) e esperar eventos serem disparados a partir de seus descendentes. A melhor maneira de fazer isso usando o .on() é:

$('table').on('click', 'td', function() {
    $(this).toggleClass('active');
});

Com essa mudança simples, o número de event listeners passou de 100 (10×10 células da tabela) para 1! Acredite: a diferença de performance entre os 2 exemplos acima é impressionante!

Se você está usando alguma versão do jQuery abaixo da 1.7, é possível fazer a mesma coisa usando .delegate(). A sintaxe é diferente, mas uma consulta à documentação vai esclarecer as coisas.

3. Manipulação de DOM

Com jQuery é fácil de manipular o DOM. É trivial criar novos nós, inserir, retirar outros, mudar as coisas ao redor e assim por diante. o código para fazer isso é simples de escrever, mas, toda vez que o DOM é manipulado, o navegador tem que revisar o DOM, o que pode ser muito custoso e impactar a performance do front-end. Um exemplo evidente em que isso acontece é em um loop longo, seja através de um loop for(), while() ou $.each().

Como exemplo, vamos supor que existe um array cheio de URLs de imagens de um banco de dados ou alguma chamada em AJAX e, o que se pretende, é colocar todas essas imagens numa lista não ordenada. Comumente, o código que se encontra para isso é:

var arr = [reallyLongArrayOfImageURLs];
 
$.each(arr, function(count, item) {
    var newImg = '<li><img src="' + item + '"></li>';
    $('#imgList').append(newImg);
});

Existem alguns problemas com isso. Para começar, há a seleção de $(‘#ImgList’) em cada iteração do loop – e, como vimos anteriormente, isso não é nada bom para a performance. O outro problema é que, a cada vez que o loop repete, é adicionado um novo li ao DOM. Cada uma dessas inserções consome recursos e, se o array é muito grande, isso poderia levar a uma grande perda de performance ou, até mesmo, ao temido alerta “Um script desta página está tornando a página lenta”…

Uma outra maneira de implementar a solução é:

var arr = [reallyLongArrayOfImageURLs],
    tmp = '';
 
$.each(arr, function(count, item) {
    tmp += '<li><img src="' + item + '"></li>';
});
 
$('#imgList').append(tmp);

O que foi feito, aqui, foi a criação de uma variável tmp para receber cada li criado. Quando o loop termina, a variável contém todos os itens de lista na memória e estes podem ser anexados ao ul todos de uma vez! Como navegadores trabalham melhor com operações de objetos na memória ao invés de diretamente atualizando o DOM a cada vez, este código é bem mais rápido e eficiente!

4. Conclusão

Logicamente, estas dicas de como otimizar códigos jQuery para aumentar a performance do front-end não são as únicas existentes, mas, certamente, estão dentre as mais simples de implementar. Embora algumas das mudanças, individualmente, façam apenas alguns milésimos de segundo de diferença, ao somar isso, dependendo de sua aplicação, é possível ter um aumento de performance de quase 70%!

Estudos mostram que o olho humano é capaz de discernir delays de 100ms (!), portanto, fazer algumas mudanças no código pode, facilmente, ter um efeito notável sobre o modo (e a percepção) de quão bem um seu site ou aplicativo é executado.

Tags | , , , , , ,