Olá pessoal. Vamos iniciar uma série importantíssima abordando javascript não-obstrutivo, tecnologia essa bastante utilizada internamente pela nossa equipe de desenvolvimento, principalmente no lançamento da atual versão do site, completamente validada pelas normas W3C.
Esta série foi publicada por Christian Heilmann, e posteriormente traduzida e adaptada por mim. Vamos abordar um conceito não muito conhecido e pouco divulgado na nossa língua, mas de suma importância para o desenvolvimento de sites que desejam seguir os padrões web.
Para não ficar um conteúdo muito extenso e sobrecarregar vocês de informações, a série será dividida em 5 etapas.
O desenvolvimento web, nos últimos tempos, vem mudando radicalmente, deixando de misturar apresentação com estrutura, e isso torna muito mais fácil a manutenção e a mudança do layout, que pode ser feito simplesmente com a mudança de uma folha de estilo.
Essa separação é possível graças à não utilização de estilos e classes diretamente nas tags, mas utilizando os seletores contextuais. Antigamente tínhamos:
HTML:
<table border="0" cellpadding="0" width="100%" cellspacing="5">
<tr>
<td>
<font face="Arial" size="-2">Lorem Ipsum</font>
</td>
</tr>
</table>E tornou-se:
CSS:
td.content {font-family:Arial,sans-serif;font-size:12px;}
HTML:
<table cellpadding="0" style="width:100%;border:none" cellspacing="5">
<tr>
<td class="content">Lorem Ipsum</td>
</tr>
</table>
Chegando finalmente a:
CSS:
body {font-family:Arial,sans-serif;font-size:12px;}
p {padding:5px;}
HTML:
<p>Lorem Ipsum</p>
Essa mesma evolução também pode ser feita com o Javascript.
Para atingimos o ideal do Javascript não-obstrutivo, temos que seguir uma série de regras básicas
Um dos grandes poderes do Javascript é que ele pode vir em um arquivo separado, semelhante ao CSS. Isso significa que você pode aplicar uma mesma coleção de funções para todas as páginas do seu site, e se você precisar alterar essas funções, basta fazê-la em um documento que a alteração será aplicada a cada página.
Ou seja, tudo que você precisará ver - exceto em algumas ocasiões especiais - no documento HTML é:
Javascript:
<script type="text/javascript" src="scripts.js"></script>
Isso é tudo, nada de Javascript inline (diretamente na tag).
O Javascript só deve ser usado para incrementar uma funcionalidade que já foi dada. N ós não podemos confiar nele, pois em alguns casos eles podem ser desativados ou filtrados por proxies, firewalls ou sistemas de anti-vírus. Não devemos nunca utilizá-lo como garantia.
Mas isso não significa que não podemos usar Javascript. Isto quer dizer que podemos apenas adicioná-lo como uma opção, e não como um requerimento.
HTML:
<form action="index.php" onsubmit="return checkform(this)">
<p>
<label for="login">Login:</label>
<input type="text" name="login" id="login" />
</p>
<p>
<label for="pw">Senha:</label>
<input type="password" name="senha" id="senha" />
</p>
<p>
<input type="submit" value="send" />
</p>
</form>
Javascript:
function checkform(f)
{
var erro='';
erro+=f.login.value==''?'\nlogin':'';
erro+=f.senha.value==''?'\nsenha':'';
if (erro!='')
{
alert('Por favor, preencha o:'+erro);
}
return erro=='';
}
É perfeitamente válido e irá prevenir que os usuários tenham que recarregar o formulário para digitar algum campo em branco.
HTML:
<form action="index.php">
<p>
<label for="login">Login:</label>
<input type="text" name="login" id="login" />
</p>
<p>
<label for="pw">Password:</label>
<input type="password" name="senha" id="senha" />
</p>
<p>
<input type="button" onclick="checkform()" value="send" />
</p>
</form>
Javascript:
function checkform()
{
var f=document.forms[0];
var erro='';
erro+=f.login.value==''?'\nlogin':'';
erro+=f.senha.value==''?'\nsenha':'';
if (error!='')
{
alert('Por favor, preencha o:'+error);
}
else
{
f.submit();
}
}
Aparentemente este código faz o mesmo, mas tem um problema: se o Javascript for desativado por qualquer motivo que seja, o botão de envio do formulário não fará nada, não importa quantas vezes o usuário frustrado clique nele. Vamos repetir: Javascript não é para ser confiado. N ão podemos depender dele.
Uma grande quantidade de erros de Javascript ocorre porque o programador é muito preguiçoso para verificar se um método ou um objeto está disponível ou não.
Javascript:
function color(o,col)
{
o.style.background=col;
}
Pode retornar um erro, se o objeto "o" não estiver disponível.
Javascript:
function color(o,col)
{
if(o)
{
o.style.background=col;
}
}
Isso sempre funcionará.
Essa técnica é, principalmente, utilizada para verificar se um navegador é capaz de suportar certa funcionalidade do Javascript. Antigamente, na época de "teste e erro", enquanto desenvolvíamos isso, era utilizada a técnica de browser-sniffing, um conceito deficiente desde o seu nascimento (toda vez que um navegador era atualizado, ou chegasse um novo no mercado, o script precisava ser atualizado). Para a maioria dos exemplos usados hoje em dia, é necessário verificar se o navegador é capaz de entender o W3C DOM, o que nos leva à próxima regra.
Ao menos que haja por uma boa razão, nós não devemos usar extensões para navegadores específicos quando estamos trabalhando com padrões web. Os tempos de verificação do document.layers (Netscape 4.x) ou document.all (Internet Explorer < 5) acabaram. Todos os navegadores modernos suportam o DOM document.getElementById, e é isso que vamos usar e testar.
Javascript:
function doDOMstuff()
{
if(document.getElementById && document.createTextNode)
{
[...]
}
}
A segunda verificação só é necessária em algumas versões recentes do Opera que tentou suportar o DOM, mas falhou em fazê-lo corretamente.
Quando nós criamos uma função ou funcionalidade, nós devemos nos certificar de que todas as variáveis usadas são locais, para evitar que uma função sobrescreva uma variável que é usada por outra.
Javascript:
var i=42; // variavel global
function facacoisas()
{
for (i=0;i<200;i++) // o i foi alterado
{
// algum codigo
}
}
function facacoisascerto()
{
var i; // definindo o i localmente
for (i=0;i<200;i++)
{
// algum codigo
}
}
alert(i); // = 42
facacoisascerto()
alert(i) // = 42 (devido a definicao local)
facacoisas()
alert(i) // = 200, opa!
Apenas se certificando que as coisas somente funcionarão quando o Javascript está ativado não é suficiente. Nós devemos também estar cientes dos usuários que não podem usar o mouse, ou tem dificuldade para manuseá-lo. Consequentemente, nós devemos nos assegurar que todas as ações realizadas pelo mouse podem ser feitas pelo teclado.
O maior problema com a independência do mouse são os elementos do formulário que são validados ou disparam alguma ação onchange ou onblur. Não os use, é simples assim.
Um uso comum dessa técnica inacessível é as caixas select de navegação.
HTML:
<form>
<p>
<label for="go2">Ir para:</label>
<select name="go2" id="go2" onchange="envia(this)">
<option value="index.html">Principal</option>
<option value="chapter1.html">Operação limpeza</option>
<option value="chapter2.html">Alcançando os objetos</option>
</select>
</p>
</form>
Javascript:
function envia(f)
{
var escolhido;
escolhido=f.options[f.selectedIndex].value;
self.location=escolhido;
}
Teste esse exemplo de select inacessível
Aparentemente, o problema principal é quando você usa o teclado para alterar o elemento, e depois pressiona a seta para baixo para selecionar alguma coisa. Você nunca pode passar a primeira opção sem que send() seja disparado quando você vai da primeira para a segunda opção, por exemplo.
Usuários experientes do teclado saberão que você tem que pressionar ALT + Seta para baixo para expandir todo o menu select antes de selecionar a opção.
Entretanto, nem todos os usuários sabem disso. Além disso, o exemplo não faz nada quando o Javascript não está disponível.
HTML:
<form action="send.php" method="post" onsubmit="return envia(this)">
<p>
<label for="go2">Go to:</label>
<select name="go2" id="go2">
<option value="index.html">Principal</option>
<option value="chapter1.html">Operação limpeza</option>
<option value="chapter2.html">Alcançando os objetos</option>
</select>
<input type="submit" value="Ir" />
</p>
</form>
Javascript:
function envia(f)
{
var chosen;
escolhido=f.go2.options[f.go2.selectedIndex].value;
self.location=escolhido;
return false;
}
PHP:
<?PHP
if(isset($_POST['go2']))
{
header('Location:'.$_POST['go2']);
}
?>
Teste esse exemplo de select acessível
Isto, em comparação, funciona bem, e nos livra de uma requisição para o script de redirecionar para send.php, que é acessado somente quando o Javascript está disponível.
Então pessoal, terminamos a primeira etapa por aqui. Espero que tenha sido útil para vocês. Aguardem a continuação, onde explicaremos como alcançar os objetos dentro da árvore do documento.
Abraço!
Obrigado pela iniciativa de abordar um tema muito importante.
Sucesso
Acho que vou ter que mudar todos os meus códigos.... pelos exemplos que você deu... os meus scripts estão totalmente errados...
:(
Parabéns Metzen, muito bom o artigo.
Espero que essa questão dos Webstandards e Javascript não-obstrusivo possa ganhar força, para que tenhamos uma internet de mais qualidade. Não aguento mais ver sites que não funcionam como devem. Já até indiquei este artigo seu lá no fórum...
Grande Metzen, muito bom o artigo/série. JavaScript não-obstrutivo é importantíssimo e pouco utilizado, principalmente aqui no Brasil.
Quem sabe os conceitos mudam. Um abraço.
Com este artigo pude ver erros que estava comentendo! realmente a matéria é muito boa! Estou aguardando a próxima!
[]s
Isso é muito bom pra quem está começando a aprender JavaScript, como eu!!!
Responder comentárioRapaz, parabéns, esperamos que vc continue com o complementos dessas dicas, estão ótimas. Obrigado.
Responder comentárioJavaScript é uma "Santa" para nós desenvolvedores. Os usuários nem sabem, mas é ela que salva todos nós !!! hehehehehe Parabéns pelo artigo. Sugestão para um próximo: HTML dinâmicamente por exemplo em uma tabela... Abraço!
Responder comentárioEstamos aguardando as próximas dicas. Valeu! Muito bem!
Responder comentárioMeu amigo, é de pessoas assim que precisamos em sites de conteúdo direcionado, que falem claramente, para que todos os leitores entendam de forma clara e objetiva o que está escrito.
Está de parabéns pelo artigo, acompanharei todos os que vc postar, principalmente, por que sei que irei aprender muito.
Muito obrigado.
No título “Mantenha o Javascript separado” há um erro nos dois códigos HTML para formulário.
A tag label para o input password deve ser <label for=“senha” ...> e não <label for=“pw”
Olá André,
Acho ótima sua iniciativa de incentivar o uso de javascript não-obstrutivo. No entanto, você nos mostrou duas formas de validação de formulário utilizando javascript, as quais não vão funcionar se o dispositivo não suportar javascript ou se esta funcionalidade estiver desativada. O correto no caso dos formulários não seria a validação do lado do servidor, utilizando PHP ou CGI?
Os textos publicados neste espaço são de responsabilidade única de seus autores (colunistas e leitores) e podem não expressar necessariamente a opinião do iMasters.
Andre Metzen é Gerente de Desenvolvimento do iMasters desde 2003, responsável pela coordenação do projeto do primeiro portal nacional completamente validado pelo W3C. É Técnico em Informática e formando em Ciência da Computação e entusiasta da nova geração da internet.
2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.