goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

jQuery e Javascript não-obtrusivo

A ideia deste post surgiu de uma conversa com o colega Francisco Prado, ontem, no Twitter. Naquela ocasião, ele sugeria uma dica rápida de Javascript: para que o valor de um campo de formulário fosse limpo ao ser clicado, basta acrescer o atributo onclick="this.value='';" ao elemento. Por meu turno, aleguei que onfocus="this.value='';" seria melhor, pois funciona mesmo se o campo tiver sido acessado pelo teclado.

Horas mais tarde, refletindo sobre isso, cheguei à conclusão de que talvez estivéssemos fazendo apenas a coisa fácil, e não a coisa certa. Nos dias de hoje, quando imperam os padrões de desenvolvimento, misturar código Javascript diretamente ao HTML chega a ser quase um crime. Ademais, isso fere uma das premissas básicas da técnica denominada Javascript não-obtrusivo: manter funcionalidade (Javascript) e aparência (HTML) separadas uma da outra. Implementar isso é um tanto quanto chato, mas, acredite em mim, facilita muito a manutenção posterior.

Mas, como se faz? Senão vejamos:

Considere este formulário HTML como exemplo:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Novo Usuário</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>

  <h1>Novo Usuário</h1>
  <form>

    <label for="nome">Nome:</label>&nbsp;
    <input type="text" id="nome"/><br />

    <label for="sobrenome">Sobrenome:</label>&nbsp;
    <input type="text" id="sobrenome" /><br />

    <label for="id">ID de usuário:</label>&nbsp;
    <input type="text" id="id"/><br />

    <label for="senha">Senha:</label>&nbsp;
    <input type="password" id="senha" /><br />

    <label for="confsenha">Redigite a senha:</label>&nbsp;
    <input type="password" id="confsenha" /><br />

    <input type="submit" value="Enviar" />

 </form>

 </body>
</html>

Temos um formulário com cinco campos (nome, sobrenome, ID de usuário, senha e confirmação da senha). Destes, desejamos que os três últimos fiquem em branco assim que ganharem foco.

O segundo passo é criar um arquivo Javascript vazio (denominei-o newuser.js) e fazer a referência a ele na seção <head> do arquivo HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Novo Usuário</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="newuser.js"></script>
  </head>
  (...)

O conteúdo do arquivo newuser.js pode ser implementado de vários modos. A grande dificuldade é que, separando o Javascript do HTML, caberá ao desenvolvedor conectar manualmente os manipuladores de eventos às funções Javascript, e fazer isso “na unha” envolve, quase sempre, ter que lidar com o modo com que os diferentes navegadores identificam o elemento que disparou o evento.

A biblioteca jQuery é uma ótima saída para este tipo de problema, já que ela lida internamente com essas diferenças de forma transparente. Utilizando-a, o conteúdo do newuser.js poderia ser semelhante ao que segue:

jQuery(document).ready(function() {

  jQuery('.clearonfocus').bind(
    'focus',
    function (e) {
      jQuery(this).val('');
    }
  );

});

Em poucas palavras, o código acima, tão logo o documento HTML esteja carregado (jQuery(document).ready), adiciona um manipulador para o evento onfocus para todos os elementos que utilizem a classe CSS clearonfocus, o qual, por seu turno, apaga o valor do elemento quando este for focado.

Por fim, precisamos fazer algumas pequenas adaptações ao código HTML original:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Novo Usuário</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="newuser.js"></script>
  </head>
  <body>

  <h1>Novo Usuário</h1>
  <form>

    <label for="nome">Nome:</label>&nbsp;
    <input type="text" id="nome"/><br />

    <label for="sobrenome">Sobrenome:</label>&nbsp;
    <input type="text" id="sobrenome" /><br />

    <label for="id">ID de usuário:</label>&nbsp;
    <input type="text" id="id" class="clearonfocus" /><br />

    <label for="senha">Senha:</label>&nbsp;
    <input type="password" id="senha" class="clearonfocus" /><br />

    <label for="confsenha">Redigite a senha:</label>&nbsp;
    <input type="password" id="confsenha" class="clearonfocus" /><br />

    <input type="submit" value="Enviar" />

 </form>

 </body>
</html>

As alterações feitas: acréscimo da biblioteca jQuery (linha 6) e adição do atributo de classe aos elementos sobre os quais desejamos ligar (bind) o manipulador de eventos (linhas 21, 24 e 27).

Este é um exemplo bastante banal, mas mostra como é possível manter Javascript e HTML separados sem perda de funcionalidade. E quanto à manutenção do código? Veja bem: se quisermos que mais algum campo tenha seu valor limpo ao ganhar foco, basta acrescentar class="clearonfocus" aos seus atributos. De forma semelhante, se desejarmos retirar esse comportamento do elemento, basta retirar o citado atributo. Em ambos os casos, mexemos só no arquivo HTML. 🙂

Anúncios

5 Respostas para “jQuery e Javascript não-obtrusivo

  1. Vedovelli 02/07/2010 às 10\1003

    Falou bonito!!! Demorei a entender o que era a porra do JS não obstrusivo, mas agora to craque! E com JQuery, mamão com açúcar!

  2. Herberth Amaral 02/07/2010 às 10\1011

    Estranho, em outro lugar eu vi falando que JavaScript não obstrusivo era, além do que você citou, uma forma do seu sistema funcionar bem com ou sem JavaScript habilitado no cliente (o que é algo bem mais difícil do que separar JS do código HTML, mas naturalmente, leva a uma flexibilidade maior).

    • goncin 02/07/2010 às 10\1021

      Herberth,

      Segundo o artigo da Wikipedia (citado no corpo do post), o Javascript não-obtrusivo se apoia, basicamente, em três premissas:

      1) Separação da funcionalidade (a “camada de comportamento”) da estrutura/conteúdo e apresentação de uma página Web;

      2) Melhores práticas para evitar problemas da programação Javascript tradicional (como inconsistências de navegadores e falta de escalabilidade); e

      3) Melhoria progressiva a fim de suportar user agents que talvez não suportem funcionalidades avançadas do Javascript.

      Você citou uma das premissas (a terceira, também chamada de graceful degradation), enquanto eu deixei explícito no post que misturar HTML e Javascript feria uma das premissas (no caso, a primeira). 😉

  3. Pingback: Tweets that mention jQuery e Javascript não-obtrusivo « goncin@wordpress.com:~$ _ -- Topsy.com

  4. Francisco 02/07/2010 às 10\1016

    Hehe, obrigado pela homenagem!

    Enfim, tenho o costume de separar os arquivos (JS/jQuery, CSS, HTML) mas, como disse, às vezes recorro à péssima mania de usar JS e CSS inline (para alguns casos banais e inusitados). 😛

    Abs

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: