» Publishers, Monetize your RSS feeds with FeedShow: More infos (Show/Hide Ads)
Depois de mais um longo inverno, O Básico da Web volta, ou tenta voltar, à ativa com mais um post sobre as maravilhas dessa linguagem não tão bem compreendida que é o javascript.
Hoje iremos falar sobre as propriedades e métodos do objeto location, um objeto do navegador que contém todas (ou quase) as informações relacionadas a URL atual. o Location é um objeto que faz parte do objeto window, logo ele é acessado pela propriedade window.location.
Não sei vocês, mas algumas coisas para mim ficam horríveis, chegando até a ficar sem sentido, quando são traduzidas, objeto do navegador é uma delas, vamos tratar todo mundo aqui como gente grande então nada de objeto do navegador é browser object!
Browser object?
Browser object porque as informações que ele retorna são do browser, inclusive elas não estão em nenhuma especificação/recomendação oficial mas a maioria dos browsers suportam, ah os IEs também estão nessa lista.
Propriedades do location
o location é um browser object muito interessante e útil, mas a maioria só conhece uma ou duas propriedade que ele possui, abaixo irei listar cada uma das propriedades e como utilizá-las
href
primeiro o href, que pega e/ou muda a url da página, sendo que ele pode ser utilizado somente como window.location, ou seja é uma propriedade que é conhecida pela metade, por exemplo, se colocarmos o seguinte js nessa pagina:
<script type="text/javascript">
alert(window.location);
//ou
alert(location.href);
//retornaria http://obasicodaweb.com/URL.
//caso façamos o seguinte código,
window.location = "http://google.com";
//ou
location.href = "http://google.com";
//a página seria recarregada para a url indicada.
</script>
hash
A outra propriedade é o hash, entre outros usos o principal é, que podemos manipular a url sem ter que fazer o recarregamento da página, ou seja, como as funções de ajax devem ser.
O hash tem um caractere padrão o # (tralha, jogo da velha, ou qualquer outro nome que vcqueira ou conheça), que é usado para identificar o que foi modificado na url, por exemplo:
<script type="text/javascript">
// estamos em uma pagina com a seguinte url:
// http://obasicodaweb.com/home#pagina2
alert(location.hash);
//retornaria #pagina2
</script>
Sim, o # vem junto da informação, caso queira removê-lo basta fazer um search ou usar o substr, mas isso é assunto para outro post.
host
Continuando, temos outra propriedade chamada host, que é chamada por location.host, que retorna o domínio e caso tenha a porta utilizada, por exemplo temos a url a seguir:
<script type="text/javascript">
// agora estamos em uma pagina com a seguinte url:
// http://www.obasicodaweb.com:8080/teste
alert(location.host);
//retornaria www.obasicodaweb.com:8080
</script>
hostname
A próxima propriedade que veremos é a hostname, que retorna, como o próprio nome diz, o hostname da url, nesta página o location.hostname retornaria www.obasicodaweb.com, basicamente o funcionamento é o mesmo do location.host, só que o hostname não retorna a porta utilizada.
Outra propriedade é pathname, que retorna tudo depois do location.host, ou seja:
<script type="text/javascript">
// a url agora é:
// http://www.obasicodaweb.com:8080/teste/teste
alert(location.pathname);
// retornaria /teste/teste
// no caso da url ser
// http://www.obasicodaweb.com:8080/teste#hash
alert(location.pathname);
// retorna /teste sem o hash ou ancora.
</script>
port
port é a próxima propriedade que veremos, ela retorna a porta utilizada na url.
<script type="text/javascript">
// na url:
// http://www.obasicodaweb.com:8080/teste
alert(location.port);
// retornaria 8080
// caso não retorne nada, é porque é a porta padrão, de numero 80, geralmente.
</script>
protocol
location.protocol é a propriedade que retorna o protocolo utilizado, no caso desta página seria http:, sim com o dois pontos. Existem diversos protocolos, outro protocolo que muito utilizado é o https:
search
search é a ultima propriedade que veremos, ela retorna os parâmetros utilizados na url, como exemplo vamos utilizar a seguinte url:
<script type="text/javascript">
// na url:
// http://www.obasicodaweb.com:8080/?largura=10&altura=5
alert(location.search);
// retorna ?largura=10&altura=5
</script>
Métodos do location
assign()
Para finalizar temos alguns métodos, o primeiro é o assign() que carrega uma nova página, parecido com o location.href, a diferença que o assign funciona como um parâmetro em uma função:
<script type="text/javascript">
window.location.assign('http://obasicodaweb.com')
// irá carregar a página indicada.
</script>
reload()
O segundo método é o reload(), que recarrega a página, basicamente faz a mesma coisa que um f5 no seu browser de preferência, é utilizado da seguinte forma:
<script type="text/javascript">
location.reload()
// recarregará a página assim que for executado
</script>
replace()
o terceiro e ultimo, mas não menos importante é o método replace(), que substitui a página por outra nova. Funciona basicamente da mesma forma que o assign().
<script type="text/javascript">
window.location.replace('http://obasicodaweb.com')
// irá substituir a página pela url indicada.
</script>
A diferença entre o assign() e href para o replace() é que os dois primeiros adicionarão a url no histórico do browser, enquanto o replace não, ou seja, você pode manipular a entrada de uma url no histórico do browser.
Por hoje é isso, espero que vocês possam utilizar tudo o que o location pode oferecer. Gostou do post? não gostou? falta algo? tem algo errado? fala ai embaixo por favor.
Algumas pessoas me escreveram e-mails com dúvidas sobre seleção de elementos HTML em JavaScript, a maioria delas com dúvidas relacionadas ao artigo sobre títulos editáveis, que publiquei por aqui há algum tempo atrás. Por isso resolvi escrever este artigo sobre esse tema tão simples, mas ao mesmo tempo tão vital para o desenvolvedor JavaScript.
Os “ganchos”
Para selecionar um elemento HTML e poder manipulá-lo via JavaScript/DOM você precisa primeiro ter algo que identifique esse elemento. Um “gancho” (em inglês, hook).
Este gancho pode ser:
- o ID do elemento
- um nome de classe
- um nome de tag (DIV, SPAN, P, A, etc)
- Um atributo ou valor de atributo específico
Dependendo do tipo de gancho usado, seu trabalho pode ser mais simples ou mais complexo. Vamos ver caso a caso.
Um elemento ou vários elementos?
Quando “pescamos” elementos HTML via JavaScript/DOM, o que temos como retorno pode ser um elemento específico ou um conjunto de elementos (um Array de elementos, pra ser mais específico).
Na verdade, o que manipulamos via JavaScript são referências a elementos HTML. Ou seja, uma variável que “aponta” para o elemento e que, uma vez modificada, reflete as modificações no elemento em si. Mas não se preocupe com isso agora. Trate as referências como elementos de fato caso isso torne as coisas mais simples de abstrair pra você.
Selecionando elementos pelo ID
A única forma de selecionar um elemento específico sem nenhum esforço extra é usando o ID do elemento como gancho. Para isso usamos o método document.getElementById().
A sintaxe deste método é simples: var elemento = document.getElementById("id_do_elemento");
Exemplo:
HTML:
<span id="preco">R$ 1500,00</span>
JavaScript:
var preco = document.getElementById('preco');
Feito isso, você pode, por exemplo, exibir um alerta com o conteúdo do elemento, assim: alert(preco.innerHTML).
E é isso. Selecionar um elemento pelo ID é muito simples. Mas nem sempre temos um ID disponível, por isso vamos ver como selecionar elementos usando outros tipos de ganchos.
Selecionando vários elementos: o processo básico
Quando você não tem um ID disponível para selecionar um elemento específico, a única opção é selecionar diversos elementos e depois “pescar” aquele ou aqueles que te interessam.
Basicamente, tudo começa com o método document.getElementsByTagName(). Como o nome já diz, este método seleciona elementos por nomes de tags.
Feito isso, basta iterar pelos elementos, usando loops (em geral, for) e, de acordo com determinadas condições, separar os elementos com os quais você precisa trabalhar. Vamos ver os exemplos mais comuns.
Seleção por nome de classe
Imagine que você quer selecionar todos os elementos que tenham a classe “preco”. Não importa se o elemento é um DIV, um SPAN ou qualquer outro, desde que tenha a classe “preco”, ele te interessa.
Para isso você vai precisar, antes de qualquer outra coisa, selecionar todos os elementos da página de uma só vez. Isto é muito simples, veja:
var todos_elementos = document.getElementsByTagName('*');
Neste caso, todos_elementos é um Array contendo todos os elementos da página. Não vou entrar em detalhes sobre Arrays por aqui. Se você já programou, em praticamente qualquer linguagem, já deve conhecê-los. Caso contrário, continue lendo que acho que vai dar pra entender mesmo assim.
Agora vamos fazer um for para percorrer todos os elementos do nosso array e selecionar apenas aqueles que têm a classe que nos interessa. Vamos assumir, para simplificar os exemplos, que você quer os elementos que tenham apenas a classe “preco”. Elementos com mais de uma classe ficam de fora.
var precos = Array();
for (var i=0; i<todos_elementos.length; i++){
var el = todos_elementos[i];
if (el.className == 'preco'){
precos.push(el);
}
}
O código acima pega todos os elementos com a classe “preco” e joga dentro de um outro Array, “precos”. Agora você pode iterar por este Array e fazer o que quiser com seus elementos.
Seleção por nome de tag
Para selecionar elementos pelo nome da tag, o método usado é o mesmo document.getElementsByTagName() e o processo é exatamente igual ao descrito acima.
Por exemplo, vamos selecionar todos os DIVs da nossa página:
var divs = document.getElementsByTagName('div');
Simples assim.
Se você quiser selecionar diretamente, por exemplo, o primeiro DIV da página, use o seguinte:
var div = document.getElementsByTagName('div')[0];
Seleção por um atributo específico
Aqui a coisa funciona da mesma maneira que a seleção por classe. Vamos selecionar, por exemplo, todos os links (tag A) com o atributo rel=”nofollow”:
var links = document.getElementsByTagName('a');
for (var i=0; i<links.length; i++){
var link = links[i];
var rel = link.getAttribute('rel');
if (rel && rel == 'nofollow'){
link.className = 'nofollow';
}
}
O código acima atribui a classe “nofollow” a todos os links com rel=”nofollow”. Com isso podemos, por CSS, aplicar uma cor diferente nesses links, por exemplo.
Como vocês podem ver, selecionar elementos via JavaScript/DOM não é nada complicado. Espero que a explicação tenha sido clara e aguardo as opiniões — e, mais importante, as dúvidas — de vocês.
Image Replacement (em português, algo como substituição por imagem), como já disse em alguns artigos por aqui, são técnicas empregadas para substituir texto por imagem, usando algumas artimanhas de CSS.
Existem diversas maneiras diferentes de se fazer Image Replacement e eu vou explicar para vocês algumas das mais famosas e interessantes, começando pela minha favorita. Além disso, vou mostrar as vantagens e desvantagens e quando devemos usar ou evitar o uso de image replacement.
A motivação
A motivação básica para o uso de image replacement é simples. Produzir texto — geralmente, mas não apenas, títulos — mais agradáveis visualmente, usando fontes mais bonitas, que componham melhor o layout da página, sem, com isso, ferir a semântica ou diminuir as chances de aparecer bem em sites de busca.
Alguns de vocês devem se perguntar: por que usar image replacement quando uma simples IMG em HTML resolveria o problema?
Posso dar duas respostas a essa pergunta:
- Porque o elemento IMG deve ser usado apenas para imagens que carreguem um significado único, que só pode ser expressado totalmente pela imagem em si. Por melhor que seja, uma descrição textual é apenas isso, uma descrição. Imagine uma foto do seu filho jogando um beijo. Agora me diga se qualquer descrição textual no mundo poderia substituir a imagem. Então, é disso que estou falando.
- Porque os mecanismos de busca dão mais valor para o conteúdo de elementos textuais — como títulos, parágrafos ou listas — do que para o conteúdo de uma imagem.
Ou seja, a primeira motivação é semântica e a segunda, marketeira. Ambas se completam e trazem benefícios tanto para o usuário quanto para o desenvolvedor.
Para entendermos melhor as motivações, vamos ao segundo ponto.
O uso
Como já vimos acima, image replacement é usada, em geral, para substituir um texto por uma imagem contendo o próprio texto, alterando apenas sua estética, sem alterar seu significado.
Um exemplo:
Texto normal:
Ao vencedor, as batatas
Texto em imagem:

Por mais que você não goste da fonte usada na imagem, é difícil não concordar que o visual é bem mais agradável que o texto puro, renderizado pelo browser.
Esse é o uso normal para image replacement. Não há problemas em decorar a imagem com bordas, sombras, cor de fundo ou qualquer outro efeito visual desejado. Mas a imagem deve conter sempre o mesmo texto que o elemento a ser substituído. Se não for esse o caso, simplesmente não use image replacement.
Por quê? Bem, por dois motivos:
- Você estaria alterando o significado da página para um ou mais grupos de usuários. Estaria entregando versões diferentes de um mesmo conteúdo baseado apenas na capacidade do usuário (na verdade, de seu user-agent) de interpretar CSS e exibir imagens. Dessa forma, você estaria ferindo a semântica (a geral, não a do HTML) de forma mortal, algo que você não quer, não é mesmo?
- Os buscadores poderiam entender esta “entrega diferenciada de conteúdo” como cloaking, uma técnica suja de otimização usada por spammers e outros tipos de desenvolvedores cuja figura materna exerce a profissão mais antiga do mundo, o que poderia lhe proporcionar uma penalização ou até mesmo, em casos extremos, fazer com que seja banido dos resultados de busca. E isso, com certeza, mais do que ferir a semântica, ninguém quer.
Portanto, resumindo, image replacement deve ser usado apenas para tornar uma página mais bonita, nunca para alterar seu conteúdo. Sugiro que você leia o meu artigo sobre desenvolvimento em camadas, para ajudar a entender melhor essas questões.
Image replacement é muito legal, muito bonito, mas, como não poderia deixar de ser, nem tudo são flores, continue lendo.
Os problemas
Para começar, nenhuma técnica de image replacement é perfeita. Cada uma delas tem seus prós e contras e escolher uma pra chamar de sua se resume a escolher a que te traz maior benefício com o menor custo.
Em geral, há dois problemas (isso está parecendo aquela propaganda do Discovery Channel, mas vamos lá):
- A técnica exclui algum grupo de usuários, geralmente aqueles que navegam, por algum motivo, com suporte a CSS mas sem suporte a imagens
- A técnica traz algum “lixo semântico”, algum elemento HTML que não precisaria estar ali se você não quisesse embelezar sua página.
Nenhuma técnica resolve os dois problemas de uma vez só, mas algumas têm os dois.
Mas, um problema — e um grande problema, diga-se de passagem — é comum a todas as técnicas de image replacement: a forma do texto não pode ser modificada pelo usuário. Ou seja, nada de redimensionamento ou mudança de cores para aumentar contraste.
Isso é algo que vai contra a acessibilidade e pode fazer com que, por exemplo, pessoas com baixa visão não consigam ler seu texto. Infelizmente, se você quiser usar image replacement, vai ter que conviver com isso. Ou melhor, seus usuários vão ter que conviver com isso. A escolha é sua.
Onde não usar
Em meu último artigo, apresentei um exemplo onde image replacement foi usado de maneira inadequada. No exemplo em questão, uma empresa estava apresentando seus produtos na home page do site e as fotos dos produtos eram inseridas na página via CSS, usando image replacement.
Como já vimos lá em cima, devemos usar image replacement apenas quando queremos substituir um texto por uma imagem contendo este mesmo texto. Qualquer outro uso deve ser evitado. Porém, há um caso clássico e muito comum de uso de image replacement que, na minha opinião, é totalmente equivocado: O logotipo do site/produto/empresa.
A princípio é tentador usar image replacement para colocar a imagem do seu logo em uma página web, já que, dessa forma, é possível colocar o seu nome e, em alguns casos, seu slogan, em um elemento com alta relevância para sites de busca (como H1, por exemplo), ajudando seu site a se posicionar melhor nas páginas de resultado.
Isto seria muito bom, se não fosse por um simples motivo: O seu logo é uma informação visual importantíssima e deve estar presente em sua forma completa, inalterada, sempre que possível.
Convenhamos, em alguns casos — provavelmente na maior parte deles — um logo é muito mais importante que o próprio nome da empresa. Imagine que você entra em um site e vê, no topo, em letras garrafais, o texto “Elma Chips”, mas não vê, em lugar algum, a carinha sorridente, presente em todos os pacotes de biscoitos desta marca? Seria, no mínimo, estranho, não?
Portanto, leve isso em conta. Se a imagem transmite, por si só, um significado único, use IMG. Dessa forma qualquer usuário que possa exibir imagens poderá ver esta imagem e os que não puderem, verão o texto contido no atributo ALT.
E agora, o momento que todos esperavam.
Técnicas de Image Replacement
Antes de mostrar as técnicas, devo dizer a vocês que estas e outras técnicas podem ser achadas facilmente pela web. Particularmente gosto dos artigos do Dave Shea (Revised Image Replacement, em inglês) e do Maujor (Técnicas CSS para image replacement, em português), tanto que vou me basear neles.
Primeiro, minha técnica favorita e a que uso sempre que necessário:
Técnica de Gilder/Levin
Criada por Tom Gilder e Levin Alexander, esta técnica usa um SPAN vazio para conter a imagem e, usando posicionamento absoluto, sobrepõe o texto com a imagem.
Esta técnica tem dois problemas (dois, de novo? Fala sério…)
- Usa um SPAN vazio. Isto pode ou não ser considerado um problema. Um elemento vazio é, de certa forma, algo que não deveria ser usado nunca. Porém isto não traz nenhum problema prático, portanto eu acredito que não devamos nos preocupar. Se você for um purista (xiita para os íntimos) e os pêlos do seu braço se arrepiarem só de pensar em usar um elemento vazio, pule para a próxima técnica. Caso contrário, continue lendo e veja o benefício trazido por esse SPAN vazio e decida-se por usar ou não.
- Impossibilita o uso de imagens transparentes. Portanto, se você precisa usá-las, essa técnica não vai te servir, infelizmente.
Porém tem um grande benefício: funciona perfeitamente para usuários com CSS habilitado e imagens desabilitadas.
Vejamos a técnica:
HTML:
<h1 id="titulo"><span></span>Ao vencedor, as batatas</h1>
CSS:
#titulo{
width:238px;
height:26px;
position:relative;
overflow:hidden;
}
#titulo span{
position:absolute;
width:100%;
height:100%;
background:#fff url(/i/ao-vencedor.gif) no-repeat;
}
Resultado:
Imagem com fundo branco:
Ao vencedor, as batatas
Imagem com fundo transparente:
Ao vencedor, as batatas
O que a técnica faz é estabelecer as dimensões do “container”, no caso o H1, exatamente iguais às da imagem, posicioná-la com posicionamento relativo (leia meu artigo sobre posicionamento, no brunotorres.net) e definir overflow hidden, para que o texto não extrapole os limites, caso o usuário o redimensione pelo browser. Depois coloca o SPAN com posicionamento absoluto e com as mesmas dimensões do “container”, com a imagem de fundo.
Note que o SPAN fica acima do H1, por causa do posicionamento absoluto. Não é necessário usar z-index.
Acho essa técnica genial e vou usá-la até que apareça algo melhor.
FIR – Fahrner Image Replacement
Esta foi a primeira técnica de image replacement, criada por Todd Fahrner, famoso desenvolvedor e membro do W3C.
Esta técnica também usa um elemento a mais, um SPAN, porém não vazio, mas seu maior problema é o uso de display:none, que pode impossibilitar que alguns leitores de tela leiam o conteúdo do elemento (Aparentemente há solução para isso, mas eu não testei com todos os leitores de tela e gente muito mais esperta que eu continua dizendo que o problema acontece, então é melhor não usá-la). Mostro-a aqui apenas por sua importância histórica.
A técnica:
HTML:
<h1 id="titulo"><span>Ao vencedor, as batatas</span></h1>
CSS:
#titulo{
width:238px;
height:26px;
position:relative;
background:url(/i/ao-vencedor.gif) no-repeat;
}
#titulo span{
display:none;
}
Resultado:
Ao vencedor, as batatas
Técnica Phark
Esta é uma técnica bastante interessante, simples e criativa, usando text-indent muito grande e negativo para joga o texto “para fora da tela”.
Tem a vantagem de ser muito simples e não requerer nenhuma marcação HTML extra e a desvantagem de não funcionar com CSS habilitado e imagens desabilitadas.
A técnica:
HTML:
<h1 id="titulo">Ao vencedor, as batatas</h1>
CSS:
#titulo{
width:236px;
height:26px;
text-indent:-9999px;
overflow:hidden;
background:url(/i/ao-vencedor.gif) no-repeat;
}
Resultado:
Ao vencedor, as batatas
Se não existisse a técnica de Gilder/Levin, esta seria a minha escolha, com certeza. Inclusive já a usei em diversos projetos.
Existem algumas outras técnicas (você pode encontrá-las nos artigos linkados no início desta seção), porém, embora o título deste texto seja “Tudo sobre image replacement”, não vou mostrá-las pois acredito que estas mostradas acima são essencialmente as mais importantes. Se vocês, no entando, encherem meu saco nos comentários, posso incluir as outras aqui.
Além das técnicas puramente de HTML/CSS, existem outras que usam PHP, Flash e JavaScript. Prefiro deixá-las para um futuro artigo, pois pertencem a uma classe diferente de image replacement.
Conclusão
Image replacement não é a panacéia do desenvolvimento web, mas pode ajudar a tornar suas páginas mais bonitas, sem afetar o conteúdo do site, embora cause alguns problemas de acessibilidade e semântica.
Use por sua conta e risco, pese os prós e contras antes de usar e nunca esqueça: seu bom senso é mais importante que qualquer regra.
Qualquer dúvida, a caixa de comentários está aí pra isso.
Image Replacement é uma técnica que permite substituir texto por imagem usando CSS. Existem diversas formas de se fazer isso, umas melhores que outras e cada uma delas com seus prós e contras. Eu já usei uma dessas técnicas por aqui em um artigo sobre menus com imagens e rollover (que, a propósito, precisa de algumas atualizações e correções).
Estas técnicas têm um apelo muito forte com relação à otimização para sites de busca mas, como tudo nessa vida, têm os lugares e situações certas para ser usadas.
A regra de ouro sobre imagens na web é: se a imagem é apenas decorativa, insira via CSS; se ela transmite algum significado não visual, ou seja, se é importante como conteúdo, insira via tag IMG no HTML.
Entrei agora há pouco no site da BlackBerry, famosa por seus smartphones, e me deparei, logo na home page, com uma situação onde uma técnica de image replacement foi usada de maneira equivocada.
A página mostra três aparelhos e, creio eu, quando queremos mostrar um produto, uma foto deste produto é algo extremamente importante, que devemos sempre tentar mostrar, não importa onde nem quando.
Se você for até a página e desabilitar o suporte a CSS vai ver apenas uma lista não ordenada com os nomes dos produtos em links para suas respectivas páginas. Limpo, leve e simples, mas, na minha opinião, errado.
Pelo menos eles não cometem o erro de usar image replacement no logo da empresa, que é um dos exemplos mais importantes de onde não se deve usá-lo. E nas páginas de cada produto, as imagens estão lá, no HTML, do jeito correto. Mas, sendo a home, geralmente, a página mais importante de um site, creio eu que deveriam dar um pouco mais de atenção à importância de mostrar seus produtos sempre, chova ou faça sol, calor ou frio, com ou sem CSS.
O que vocês acham? Alguém tem mais algum exemplo de mau uso de image replacement?
Hoje à tarde meu amigo Jânio me apareceu no MSN com um problema interessante: ele estava fazendo um JavaScript que deveria abrir uma nova janela, com uma determinada largura e uma determinada altura. Nada mais simples, você pode pensar. Eu também pensei e ele também.
Acontece que no firefox a janela abria com uma largura mais ou menos igual à metade do valor que ele tinha colocado no parâmetro width do método window.open(). Estranho, não?
Pra quem não conhece, window.open() é um método que simplesmente serve para abrir uma nova janela. O uso é assim:
//window.open(URL, nome_da_janela, parâmetros);
//ex:
window.open('teste.html', 'janela1', 'width=500,height=400');
Tem mais parâmetros, mas isso não vem ao caso agora. O fato é que eu fiz diversos testes e realmente a janela nunca abria com a largura certa no Firefox.
Então, procura daqui, procura dali, dando uma olhada na referência de DOM do Mozilla Developer Center, mais precisamente nos métodos do objeto window, achei a solução.
Há três parâmetros referentes à largura da janela:
- outerWidth
- Define a largura da janela inteira do browser, incluindo barras de rolagem, etc e tal. só é suportada por browsers gecko (família Mozilla e Netscape)
- width
- Define a largura do viewport, ou seja, da área útil do browser, a área onde é exibido o conteúdo da página.
- innerWidth
- A mesma coisa que width, mas só é suportada por browsers gecko.
Esses parâmetros são aplicados na ordem de precedência acima. O outerWidth é o mais “forte”, ou seja, seu valor “ganha” dos outros dois. width vem logo depois, seguido de innerWidth.
A solução para o problema em questão era usar o outerWidth que, por algum motivo que eu não sei exatamente explicar, funciona direitinho, ao contrário do width. Porém, como outerWidth só funciona nos browsers gecko, temos que usar width também, para agradar ao IE, opera e, creio eu, safari. Nosso código ficou assim:
window.open('teste.html', 'janela1', 'width=500,outerWidth=500,height=400');
Note que, caso a janela a abrir tenha barra de rolagem vertical, vai ser necessário setar outerWidth para um valor ligeiramente maior que width, para obter o mesmo resultado em todos os browsers. Mas, em geral, 10 pixels mais ou menos, não matam ninguém.
Fica a dica, caso algum de vocês venha a ter o mesmo problema.
Parece óbvio, não? Mas infelizmente não é tão óbvio quanto parece. Muitos sites por aí estão regredindo vários passos na escala evolutiva da web e criando formulários que só submetem com um clique do mouse em um botão ou um ENTER quando o mesmo botão tem o foco.
Esse tipo de problema é devido, praticamente sempre, ao desejo de fazer alguma coisa “legal” com o formulário, sempre usando JavaScript e AJAX.
E a solução é tão simples: coloque um botão de submissão comum em seus formulários.
Exemplos comuns desse tipo de formulário são campos de busca e formulários onde você deve entrar apenas seu email, por exemplo, para se inscrever em algum tipo de serviço.
Nesse tipo de formulário, o comportamento padrão do usuário é digitar e apertar ENTER. Veja como é fácil fazer isso funcionar:
<input type="text" name="email" size="50">
<input type="submit" value="Enviar">
Simples assim. A não ser que o campo onde os dados devem ser digitados seja uma TEXTAREA, um ENTER dentro do campo de texto vai submeter o formulário, enviar os dados para o servidor e, com sorte, trazer uma resposta para o usuário.
Se você quiser fazer algo bonito, com AJAX e tudo mais, faça em outra camada. Na camada de comportamento. Já falei sobre isso aqui em alguns posts então não vale a pena gastar espaço falando de novo.
A moral da história é: não torne o que é simples complicado. Até porque acaba sendo mais complicado pra você também.
Em alguns casos precisamos usar alguns elementos HTML que só têm função quando há suporte a javascript, nas página que estamos desenvolvendo.
Nesse caso, o mais sensato a se fazer é criar esses elementos via JavaScript. Dessa forma eles só estarão disponíveis para o usuário caso o browser que ele estiver usando tenha suporte a javascript, ficando fora do caminho caso contrário. Assim, não criamos expectativas frustradas no usuário e temos uma página cujas funcionalidades são coerentes com o ambiente onde ela está sendo exibida.
Criar elementos via javascript não é nenhum bicho de sete cabeças. Há duas maneiras interessantes (e algumas outras não interessantes) de se fazer isso:
- Adicionando conteúdo ao innerHTML do elemento em questão
- Criando um objeto DOM e inserindo dentro da página via DOM API
A primeira é mais fácil e, segundo alguns testes (cujos links não tenho agora, mas vou procurar), mais rápido que o segundo. Porém não faz parte de nenhum padrão DOM e pode causar problemas em alguns casos raros, como por exemplo se você estiver usando XHTML e enviando ao browser como uma aplicação de XML. Como ninguém em sã consciência, que esteja pretendendo fazer um site com o máximo de compatibilidade faria isso, não precisa se preocupar.
A segunda segue padrões mais rígidos e vai funcionar sempre que houver um suporte decente ao DOM. Grosso modo, é menos compatível que a primeira, e devemos sempre testar a presença dos métodos necessários a sua execução antes de criar os elementos.
Vamos então aos códigos:
Usaremos o seguinte exemplo: Imagine que você tenha em sua página um botão cuja função é esconder ou mostrar um determinado conteúdo. Digamos que esta funcionalidade esteja implementada apenas por meio de JavaScript. Você não vai querer que os usuários que não tenham suporte a javascript vejam o botão e sintam-se frustrados ao clicar e nada acontecer, vai?
Portanto é importante que esse botão seja criado via JavaScript.
Criando elementos via innerHTML
innerHTML é uma propriedade que permite ler ou modificar o conteúdo HTML de um elemento HTML. Exemplo:
<p>Site do <a href=http://w3.org/>W3C</a></p>
No caso acima, o innerHTML do elemento P é “Site do <a href=http://w3.org/>W3C</a>“. Entendeu? Simples, não é?
No nosso exemplo, precisamos criar algo do tipo:
<button type="button" id="toggle">Esconder/Mostrar</button>
E depois adicionar a esse botão, via JavaScript, a funcionalidade desejada.
Antes de criar o elemento precisamos definir onde o elemento deve ser colocado. Ou seja, precisamos decidir qual será o elemento “pai” deste nosso botão.
Digamos que você tenha um DIV e que este DIV tenha o ID “conteudo”. Dentro deste DIV está o conteúdo que deve ser exibido ou escondido, dependendo do caso. O botão entraria, então, ao fim deste DIV.
Este é o código HTML do DIV conteudo:
<div id="conteudo">
<div class="texto">
<p>Aqui entra o texto.</p>
<p>Poderíamos ter um DIV apenas, mas optei por usar dois para facilitar o exemplo.</p>
</div> <!-- /texto -->
</div> <!-- /conteudo -->
Vamos lá. O primeiro passo é acessar o DIV pelo JavaScript:
var conteudo = document.getElementById('conteudo');
Jogamos uma referência ao elemento cujo ID é conteúdo para uma variável criativamente nomeada “conteudo”. Isso significa que tudo que fizermos com esta variável será aplicado de fato ao elemento referenciado.
O passo seguinte é criar o código do nosso elemento. Vamos colocá-lo em uma variável também:
var button = '<button type="button" id="toggle">Esconder/Mostrar</button>';
A variável button é uma string que contém o código do nosso botão. Agora basta colocar esse código dentro do DIV conteudo:
conteudo.innerHTML += button;
O operador += tem o efeito de adição. No caso acima é o mesmo que conteudo.innerHTML = conteudo.innerHTML + button.
Agora só falta adicionar a função javascript desejada, o que faremos ao fim do texto.
Criando elementos via DOM API
Criar elementos via DOM API não é tão simples quanto via innerHTML. Primeiro precisamos criar o elemento, depois adicionar suas propriedades e atributos e, por fim, adicioná-lo ao conteúdo da página. Acompanhe comigo.
Criando o elemento:
var button = document.createElement('button');
A linha acima cria o elemento e associa este elemento à variável button. Note que, embora tenha sido criado, o elemento ainda não está visível no documento. Continuemos.
Precisamos, agora, adicionar os atributos TYPE e ID ao botão:
button.setAttribute('type', 'button');
button.setAttribute('id', 'toggle');
Agora vamos adicionar o texto “Esconder/Mostrar” ao botão. Primeiro precisamos criar este texto no documento em uma variável e depois adicioná-lo ao botão. Assim:
var btntext = document.createTextNode('Esconder/Mostrar');
button.appendChild(btntext);
Como no outro exemplo, precisamos criar uma variável que referencie o elemento “pai”, ou seja, o DIV conteudo:
var conteudo = document.getElementById('conteudo');
E, por fim, adicionar o botão ao elemento pai:
conteudo.appendChild(button);
Ou seja, adicionamos um “filho” ao “pai” conteudo. O filho é o nosso famoso botão.
Claro que podemos adicionar elementos em outros lugares além do fim de um outro elemento, mas isso é um pouco mais avançado e fica para um outro post.
Adicionando funcionalidade ao elemento
O elemento que criamos é, até então, inútil. Vamos adicionar funcionalidade a ele. Para isso vamos usar a seguinte função:
function toggle(el) {
if ( el.style.display != 'none' ) {
el.style.display = 'none';
}
else {
el.style.display = '';
}
}
Esta função pega uma referência a um elemento como parâmetro e exibe ou esconde este elemento, dependendo do seu estado atual.
Antes de aplicar a função, vamos criar uma variável que referencie o conteúdo que será escondido ou exibido que é, no nosso caso, o DIV cuja classe é “texto” e que está dentro do DIV conteudo:
var texto = conteudo.getElementsByTagName('div')[0];
A função getElementsByTagName vai pegar todos os elementos dentro de “conteudo” que sejam definidos pela tag <div>. Essa função retorna um Array, que terá tantas posições quantos elementos existam. O [0] significa que queremos a primeira posição que, no nosso caso, é a única. (Preciso explicar melhor Arrays e getElementsByTagName. Mais uma promessa…)
Primeiro vamos adicionar esta função ao evento onclick — que é executado quando o elemento é clicado com o mouse — do botão:
button.onclick = function(){ toggle(texto); }
Depois, vamos adicioná-la ao evento onkeypress — que é executado quando o usuário digita alguma tecla enquanto tem o elemento em foco –, checando antes se a tecla pressionada foi ENTER:
button.onkeypress = function(e){
var keynum;
if(window.event) // para o IE
keynum = window.event.keyCode;
else if(e.keyCode) // Netscape/Firefox/Opera
keynum = e.keyCode;
if (keynum == 13) {
toggle(texto);
}
}
E assim temos o nosso elemento criado e funcionando.
Fazer um texto deste tamanho sobre o assunto pode fazer com que pareça mais difícil do que é, por isso veja os exemplos abaixo, com os códigos consolidados, para entender melhor como funciona e ver que não é nenhum bicho de sete cabeças:
Podemos fazer maravilhas com JavaScript e, com a popularização das chamadas HTTP via JavaScript (mais conhecidas como AJAX) e posteriormente do que chamam de web 2.0, essa linguagem de scripts, tão mal falada e quase esquecida em um passado não muito distante, voltou à tona e é usada, hoje, por 9,9 entre 10 desenvolvedores web.
O problema é que, na maioria dos casos, os desenvolvedores não se limitam a usar o JavaScript onde ele é realmente necessário e traz realmente algum ganho de produtividade e usabilidade para o usuário, e acabam abusando da linguagem e, pior ainda, fazendo com que funcionalidades e conteúdo estejam acessíveis apenas quando houver suporte a JavaScript.
A idéia desse texto não é falar mal do JavaScript e sim mostrar a vocês como fazer com que ele não fique no caminho do usuário, ou seja, fazer com que o que funciona com JavaScript também funcione sem JavaScript.
Na verdade, é o contrário, a idéia é usar sempre o conceito de progressive enhancement (explico melhor em outro post, se vocês acharem necessário), que é, basicamente, o uso racional e correto do desenvolvimento em camadas. Algo tão simples quanto começar do começo, dar um passo de cada vez para chegar a um resultado satisfatório.
Tenha em mente que, por mais que existam poucos usuários que navegam sem JavaScript, um desses usuários pode ser um grande cliente em potencial navegando de um PDA ou o Google.
Enfim, vamos ao que interessa. Comecemos pelo exemplo mais simples.
Não existe protocolo javascript, portanto não é certo usar javascript:
Isso mesmo. Atire a primeira pedra aquele que nunca fez isso:
<a href="javascript:fazAlgumaCoisa();">Clique aqui para fazer alguma coisa</a>
O atributo HREF do elemento A (o popular anchor, ou link para os íntimos) foi feito especificamente para definir uma URI. Uma URI é composta por algumas partes e a primeira delas é o protocolo (na verdade, um esquema, mas vamos chamar de protocolo porque é o nome mais comum. Prometo explicar isso melhor outro dia também), que deve ser algo como http:, ftp:, mailto:, etc e tal. javascript: não faz parte dessa lista. Não é um esquema, não é um protocolo. Não use sob hipótese alguma.
Outra coisa importante é: só use links se realmente tiver algum lugar para apontar usando HREF. Se o propósito é totalmente outro, use outro elemento. Veremos isso mais a frente no texto.
Tá bom, eu não uso, mas como eu faço então, tio?
Há varias maneiras. Algumas melhores, outras piores. Vejamos:
<a href=http://meusite.com/teste.html onclick="fazAlgumaCoisa();return false;">Link de teste</a>
O que estamos fazendo na linha acima é um link para uma URL que existe e, caso haja suporte a JavaScript, ao ser clicado, esse link vai executar a função fazAlgumaCoisa(), definida em algum outro lugar.
Notem o return false depois da chamada da função. Ele serve para que o clique seja cancelado após executar a função. Se esquecer dele, o usuário será levado à URL em questão depois de executar a tal função e, em geral, não é isso que você quer, não é?
Mas esse modo tem alguns problemas:
- Não separa o comportamento do conteúdo. Ou seja, você está misturando as camadas, o que não é bom por diversos motivos.
- Só funciona para o evento de clique do mouse. Usuários que sigam o link via teclado não vão ter a funcionalidade do script, o que pode ser o efeito desejado, mas, em geral, não é.
Como resolver isso então?
Separando o JavaScript do HTML. Para isso, você precisa definir algo para identificar esse link em específico e poder acessá-lo pelo JavaScript. Vamos usar um ID para o nosso exemplo:
<a href=http://meusite.com/teste.html id="linkteste">Link de teste</a>
Um link simples. Vamos agora adicionar a funcionalidade em um JavaScript externo:
function powerLinks(){
var link = document.getElementById('linkteste');
link.onclick = function(){
fazAlgumaCoisa();
return false;
}
}
window.onload = powerLinks;
Ou seja, redefinimos o evento onclick do link e adicionamos o nosso código nele. Simples, não? A última linha faz com que a função seja executada ao carregar a página (existem formas melhores de fazer isso, mais uma promessa para um outro post. Me cobrem, por favor).
Mas ainda temos o problema do mouse. Precisamos fazer com que o script funcione também para quem está navegando via teclado.
Fazemos isso usando o evento onkeypress, que é ativado quando o usuário aperta alguma tecla, e checando se a tecla pressionada foi o ENTER. Veja como:
function powerLinks(){
//aqui entra o codigo anterior do script
link.onkeypress = function(e){
var keynum;
if(window.event) // para o IE
keynum = window.event.keyCode;
else if(e.keyCode) // Netscape/Firefox/Opera
keynum = e.keyCode;
if (keynum == 13) {
fazAlgumaCoisa();
return false;
}
}
}
Como vocês podem perceber, o IE trata o evento onkeypress um pouquinho diferente dos outros browsers, mas nada ultra complicado. 13 é o número de tecla correspondente ao ENTER. Ou seja, quando o usuário pressionar ENTER, o script será executado.
E quando não houver URL pra usar no HREF?
Bem, nesse caso então você não tem um link e, claro, não deve usar o elemento A. Use qualquer outra coisa e, via CSS, faça com que essa coisa se pareça com um link e, de preferência, crie essa coisa com JavaScript, para que aqueles que não têm suporte a JavaScript nem vejam a tal coisa.
Infelizmente, não é qualquer elemento que pode receber o foco via teclado, portanto se a sua idéia é que esse elemento seja acessível via teclado, não há outro jeito senão usar um A. Porém, como esse A será criado na página via JavaScript, ele não vai incomodar ninguém que não tenha suporte a scripts. Exemplo:
function criaPseudoLink(){
var paiPseudoLink = document.getElementById('pai') //o elemento que conterá o pseudo link
paiPseudoLink.innerHTML += '<a href="#" id="linkteste">Faz Alguma coisa</a>';
}
Ou seja, o conteúdo do elemento “pai” do pseudo link , cujo ID é “pai” será acrescido do HTML correspondente ao A. O resto é igualzinho ao que foi descrito anteriormente.
Por hoje é só. Ficou claro? Alguma dúvida? Esqueci de algo? Falei alguma besteira? A caixa de comentários é toda de vocês.
Para não deixar o post ainda mais longo, vou abordar outros tipos de abusos de JavaScript em outro post. E, como já disse, me cobrem, por favor.
Depois de um longo inverno, estou pretendendo voltar a escrever por aqui. Como o meu blog principal, Bruno Torres ponto net vem mudando de foco com o tempo (e acredito que vá mudar muito ainda, de acordo com as mudanças na minha vida, tanto pessoal quanto profissional) acho que esse aqui é o espaço ideal para voltar a escrever textos sobre desenvolvimento web.
O meu maior problema em voltar a escrever aqui é que acho que esse nome “O básico da web” tem me feito sentir um pouco engessado sobre os temas que devo abordar.
Além disso, comecei a fazer posts em série, no estilo curso de html, e isso acabou não me agradando, e a vontade de continuar escrevendo foi diminuindo.
Porém, este blog tem hoje incríveis 900 assinantes, o que é muito para um blog tão pequeno, com tão pouco conteúdo. Imagino que boa parte desses assinantes (ou seja, vocês, que estão lendo isso agora) vieram do outro blog e isso me faz pensar mais duas vezes antes de escrever. E aí acabo não escrevendo.
A minha idéia com esse post é tentar entender o que vocês esperam encontrar por aqui. Eu acho que devo abandonar esse esquema de posts sequenciais sobre um mesmo tema e escrever sobre o que me der na telha, ou o que estiver em foco ou, melhor ainda, o que vocês quiserem.
Sendo assim, peço àqueles que estiverem afim de ajudar, que usem o formulário de contato, ou me escrevam um email diretamente, ou façam comentários, sugerindo temas, me ajudando a definir qual o futuro do conteúdo desse espaço.
E então. Alguém afim de ajudar? Não precisa fazer trackback nem pingback (aliás, se não souberem o que é isso, me avisem
). Só quero idéias e sugestões para fazer desse espaço um lugar melhor para aqueles que querem aprender mais sobre a web.
Conto com vocês!
Vamos continuar a falar sobre os elementos que compõem o HEAD de um documento HTML.
Elemento STYLE
O elemento STYLE serve para aplicar estilos diretamente dentro do documento HTML. É importante notar que para reforçar a questão da separação em camadas, devemos evitar ter estilos aplicados desta forma.
Vejamos um exemplo:
<style type="text/css" media="screen">
body{ font: normal 1em verdana, helvetica, sans-serif;}
div{ width: 750px; padding:10px; }
</style>
O elemento STYLE também pode ser usado para referenciar um documento CSS externo. Isso já foi muito usado para “esconder” os estilos de browsers antigos (como o Netscape 4), porém tome cuidado pois pode causa um efeito chamado FOUC, que faz com que, por um pequeno espaço de tempo, o conteúdo apareça sem nenhum estilo. Este problema é resolvido incluindo um ou mais elementos SCRIPT ou LINK dentro do HEAD do seu documento.
<style type="text/css" media="screen">
@import url(estilo.css);
</style>
Hoje esta forma já não é a única forma simples de se esconder estilos de browsers antigos. Usar um LINK com duas ou mais mídias, separadas por uma vírgula e um espaço, no atributo media, tem o mesmo efeito:
<link rel="stylesheet" type="text/css" href="estilo.css" media="screen, projection">
Elemento SCRIPT
O elemento SCRIPT serve tanto para conter scripts inteiros quanto para referenciar um script externo. Geralmente esses scripts são escritos na linguagem JavaScript. Exemplo:
<script type="text/javascript">
window.onload = function() { alert('Olá, mundo!') }
</script>
Desta forma, o script inteiro está contido no elemento SCRIPT.
Apesar de ser, em geral, melhor colocar todos os elementos SCRIPT de uma página dentro do HEAD, isso não é mandatório. Algumas vezes pode ser necessário que o script esteja localizado dentro do corpo (BODY) do documento e não há grandes problemas nisso. Falaremos desse assunto em breve, mas você pode ver algumas coisas sobre JavaScript no meu artigo sobre a camada de comportamento.
A outra forma de se usar o elemento SCRIPT é com o atributo src contendo a localização (URL) de um arquivo de script externo:
<script type="text/javascript" src="http://www.obasicodaweb.com/js/script.js"></script>
Desta forma o script contido no arquivo script.js será executado logo que o elemento SCRIPT for interpretado pelo browser.
É importante notar que, de todos os elementos contidos no HEAD, apenas o SCRIPT precisa de uma tag de fechamento. E é vital que você nunca esqueça dessa tag de fechamento, pois pode fazer com que sua página apareça totalmente em branco em alguns browsers. Já já vamos entender porque alguns elementos precisam ser fechados e outros não e porque alguns tem conteúdo e outros não. Sejam pacientes.
Elemento NOSCRIPT
O elemento NOSCRIPT serve para definir um conteúdo alternativo a um script, que apenas será exibido caso o user-agent usado não tenha suporte a scripts ou esteja com esse suporte desabilitado.
Em geral, devemos desenvolver nossas páginas de forma que a camada de conteúdo seja, por si só, suficiente para que um usuário possa executar qualquer tarefa. Porém, em alguns casos, isso não é possível. Sendo assim, devemos usar o elemento NOSCRIPT para informar ao usuário que seu user-agent não tem suporte a scripts e que uma determinada função da página só pode ser usada (ou visualizada) na presença deste suporte. Exemplo:
<noscript>
<p>É necessário que haja suporte a javascript para que a função x bla bla bla</p>
</noscript>
Assim como o elemento SCRIPT, o NOSCRIPT pode ocorrer tanto dentro do HEAD quanto dentro do BODY de um documento HTML.
E aqui termina o que tinha a ser dito sobre o elemento HEAD e seus “filhos”. Com certeza, em artigos futuros desta mesma série, voltaremos a falar destes elementos, para explicar alguma especificidade que não tenha sido necessária explicar até aqui ou que necessite de algum conceito que ainda vamos aprender. Continuem comigo!
Vamos continuar desmontando o esqueleto básico do nosso documento HTML de exemplo. Antes de começar essa parte, vamos relembrar o código de exemplo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="pt-br"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Título da minha página</title> <link rel="stylesheet" href="/c/style.css" type="text/css" media="screen, projection"> </head> <body> <div id="conteudo"> </div> </body> </html>
O que nos interessa para este post é o código que vai da linha 2 à linha 7 do código acima. O elemento HTML e o elemento HEAD e seus “elementos-filho”.
Elemento HTML e o atributo lang
O elemento HTML é descrito pela tag <html>, e é o elemento raiz de todo documento HTML.
Segundo o DTD do HTML 4.01 Strict, o elemento HTML não precisa ter nem sua tag de abertura nem sua tag de fechamento declaradas no documento. Isso acontece com diversos outros elementos e você vai poder checar por si mesmo cada um deles quando estivermos estudando a leitura e interpretação de DTDs.
Porém, como boa prática, vamos sempre usar as tags de abertura e fechamento para todos os elementos, salvo algumas exceções.
O mais importante de estudarmos com relação ao elemento HTML não é o elemento em si, mas sim seu atributo lang.
O atributo lang pode ser usado em quaisquer elementos do HTML, porém ele é especialmente importante para o elemento HTML, pois serve para definir o idioma predominante no documento.
No caso do nosso documento de exemplo, o idioma que estamos declarando é o pt-br, ou seja, português do Brasil.
O valor do atributo lang pode ser apenas um código de idioma ou um código de idioma seguido de um código de país.
Códigos de idioma devem seguir o padrão ISO-639-1 (códigos de duas letras) ou o ISO-639-2 (códigos de três letras). Você pode ver os valores possíveis em ambos os padrões na página de listagem de códigos de idioma, no site da biblioteca do congresso americano.
Códigos de país com duas letras devem seguir o padrão ISO-3166.
Não pode haver espaços dentro do atributo lang e os códigos de idioma e país devem ser separados por um hífem (-).
Declarar o idioma base do documento no elemento HTML é importante e essa informação pode ser usada, por exemplo, por um leitor de tela, para selecionar o idioma correto em que o documento será lido ou por um mecanismo de busca para classificar corretamente uma página em seus índices.
Quanto ao elemento HTML em si, não temos grandes coisas a falar. Sua tag de abertura deve vir logo após o DOCTYPE e sua tag de fechamento deve estar na última linha do documento. Ponto.
Elemento HEAD e seu conteúdo
O elemento HEAD deve ser declarado logo após a tag de abertura do elemento HTML e sua função é, basicamente, descrever meta-informações sobre o documento.
Essas meta-informações podem ou não ser visíveis para o usuário e algumas fazem sentido apenas em um determinado contexto ou para um determinado user-agent.
Os elementos que compõem o HEAD são: TITLE, o título do documento; META, descritor genérico de meta-informação, que tem diversas funções que veremos a seguir; LINK, que, ao contrário do que se pode pensar, não é o elemento que cria links dentro de um texto e, sim, links para formas alternativas de conteúdo, estilos CSS, páginas vizinhas, índices, e outras coisas mais; STYLE, que serve para declarar estilos dentro do próprio documento; SCRIPT, geralmente usado para conter ou referenciar scripts em JavaScript, mas pode ser usado para scripts em outras linguagens também; NOSCRIPT, que define um conteúdo a ser exibido caso o user-agent não tenha suporte a scripts
Vamos entender melhor cada um desses elementos:
Elemento TITLE
O título do documento. O elemento cujo conteúdo é mais relevante para os mecanismos de busca na hora de indexar e ranquear uma página.
Deve haver um, e apenas um, TITLE por documento HTML. Seu conteúdo deve, preferencialmente, descrever de forma simples e clara o conteúdo do documento e, em browsers gráficos, é o que será exibido no topo da janela do browser, em geral ao lado do nome deste.
Elemento META
Como já disse, existem diversos tipos de informação que podem ser descritas pelo elemento META. Alguns exemplos são:
O tipo de conteúdo e o conjunto de caracteres usado no documento: O META exibido no exemplo é desse tipo. Declara que o documento é do tipo text/html (ou seja, HTML) e que o conjunto de caracteres usado no documento é o UTF-8. Será usado pelo browser caso esta informação não seja enviada pelo servidor, no cabeçalho HTTP. Sempre declare este META como primeiro elemento do HEAD. Quanto antes ele vier no documento melhor, pois, caso ele precise ser usado, o browser terá que fazer uma releitura do documento e é melhor que isso seja feito enquanto poucos bytes, e principalmente, apenas caracteres ASCII, foram lidos.
O http-equiv indica que este META é uma informação equivalente a um cabeçalho HTTP.
<meta http-equiv="content-type" content="text/html; charset=utf-8">
Descrição do documento: uma breve descrição do conteúdo do documento, que pode ser usada por sites de busca como descrição do site em suas listagens.
<meta name="description" content="Coloque aqui a descrição do site">
Palavras-chave: listagem de palavras-chave relevantes ao conteúdo do documento, que podem ser usadas por sites de busca (embora hoje já não sejam mais tão relevantes) e, supostamente, para outros fins, como escolha de anúncios do Adsense, por exemplo.
<meta name="keywords" content="basico,web,html,http">
Além destes exemplos de META, existem outros vários. Vamos vê-los no momento oportuno.
Elemento LINK
O elemento LINK define uma relação entre o nosso documento e outros documentos. Existem diversos tipos de relações que podem ser definidas.
O tipo de relação entre os documentos é descrita pelos atributos rel e rev.
Para entender a diferença entre rel e rev, tente pensar da seguinte forma: Se você diz “O documento X é uma versão alternativa do meu documento”, você deve usar rel; já se você disser “O meu documento é uma versão alternativa do documento X”, use rev.
Calma, vai ficar mais claro com os exemplos.
Vejamos alguns:
Documentos adjascentes e índices
Imagine um livro online. Você está escrevendo o documento que tem o conteúdo do capítulo 2. É interessante criar LINKs para o capítulo anterior, o próximo capítulo e o índice do livro. Esses LINKs podem ser usados, por exemplo, pelo browser, que pode fazer um pré-carregamento destas páginas enquanto estiver parado. Existe uma extensão para o Firefox que expõe, na barra de status, os LINKs presentes no documento. Chama-se Link Widgets.
Exemplos:
<link rel="Next" href="/capitulo-2">
<link rel="Previous" href="/capitulo-1"
<link rel="Index" href="/">
Pense: “O capítulo 2 é o próximo capítulo em relação a mim, que sou o capítulo 1″. rel na cabeça. Também seria certo, por exemplo:
<link rev="Previous" href="capitulo-2">
Ou seja: “Eu sou o capítulo anterior ao capítulo 2″. Pescou?
Versões alternativas
O tipo mais comum de versão alternativa são os feeds RSS e ATOM.
<link rel="alternate" type="application/rss+xml" href="/feed">
Note o atributo type. Ele descreve o tipo do documento que estamos referenciando. No caso, um feed RSS. Caso não seja declarado, entende-se que seja do mesmo tipo que o documento onde se encontra o link, no caso, text/html.
Além de feeds, podemos ter outros tipos de versões alternativas. Um PDF, por exemplo:
<link rel="alternate" type="application/pdf" media="print" href="arquivo.pdf">
Aqui entra em cena o atributo media, que define que este documento só fará sentido como uma versão alternativa, caso esta mídia esteja sendo usada. No nosso caso, print, ou seja, impressão.
Folhas de estilos CSS
Podemos usar o elemento LINK para aplicar uma folha de estilos CSS a um documento HTML. Exemplo:
<link rel="stylesheet" type="text/css" href="estilo.css" media="screen">
Este link diz que o documento referenciado é uma folha de estilos para o nosso documento, do tipo text/css e que deve ser aplicado apenas quando a media screen (ou seja, tela) esteja sendo usada.
Bem, o artigo já está longo demais. Vamos deixar o restante dos elementos do HEAD para amanhã. Até lá.
Ontem vimos uma introdução ao HTML. Sim, eu sei, foi chata. Mas não tinha muito jeito, era necessário apresentar alguns conceitos àqueles que estão realmente começando a estudar HTML.
Hoje, pra começar a ficar um pouco mais interessante, vamos colocar a mão na massa. Vamos ver como é a base de um documento HTML e entender como funciona e pra que serve cada uma de suas partes.
Pra começar, um documento de exemplo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="pt-br">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Título da minha página</title>
<link rel="stylesheet" href="/c/style.css" type="text/css" media="screen, projection">
</head>
<body>
<div id="conteudo">
</div>
</body>
</html>
Isso que vocês vêem aí em cima é nada mais nada menos que um documento HTML.
Vamos entender o que está descrito ali em cima e pra que serve cada um desses códigos malucos.
Bem, eu sei que disse que isso ia começar a ficar interessante. Não era totalmente verdade. Neste post vamos falar sobre a primeira linha do nosso documento de exemplo. A declaração de DOCTYPE. Pode ser um pouquinho chato, mas, acreditem, é muito importante. Vamos a ele.
DOCTYPE
A primeira linha de todo documento HTML deve ter uma declaração de DOCTYPE. Nunca se esqueçam, sempre na primeira linha, explico porque depois.
O DOCTYPE é uma referência a um DTD, que significa Document Type Definition (em português, Definição de Tipo de Documento). Um DTD é um documento onde estão definidas as regras para a criação de um documento HTML (existem DTDs pra outros tipos de documento, mas vamos manter o foco). Nele estão descritos os elementos que podem ser usados, quais elementos podem estar dentro de outros elementos, que tags descrevem esses elementos, se um elemento tem conteúdo ou não, se é necessário ter tag de abertura e/ou de fechamento. Enfim, tudo que pode ou não ser usado dentro do nosso documento.
Mais a frente vamos ver como ler e entender um DTD, por enquanto vamos nos ater ao DOCTYPE do nosso documento apenas.
Uma declaração de DOCTYPE é dividida em duas partes, um identificador público (public identifier) e uma URI.
O identificador público diz que tipo de documento está sendo usado:
-//W3C//DTD HTML 4.01//EN
Este é o identificador público do HTML 4.01 Sctrict, que é o que vamos usar daqui pra frente, em todos os nossos exemplos.
A URI aponta para o endereço do DTD na web:
http://www.w3.org/TR/html4/strict.dtd
Note que no exemplo acima, nosso DOCTYPE está dividido em duas linhas. Se você preferir, pode usar uma linha apenas, mas tome o cuidado de incluir um espaço entre o identificador público e a URI.
É extremamente importante identificar o DOCTYPE em todos os seus documentos HTML. Caso contrário, seu browser pode interpretar seu documento de maneira estranha, causando problemas que seriam facilmente evitados caso o DOCTYPE estivesse presente.
Um browser, ao encontrar a declaração de DOCTYPE não vai ler o documento referenciado em sua URI e interpretar o HTML de acordo com ele. Porém, ele vai se basear no identificador público e na presença ou não de uma URI para decidir como interpretar o documento. Na verdade, isso vai influir na maneira como estilos CSS são aplicados ao documento HTML.
Em geral, os browsers têm duas formas de interpretar um documento: Strict Mode, ou Standards Compliance Mode, onde as especificações são seguidas à risca e Quirks mode (Modo de compatibilidade), onde o browser vai deixar passar alguns erros, interpretando o documento mais ou menos como versões mais antigas de browser o fariam. Vamos estudar com calma estes modos de interpretação (além de um outro, usado pelo Mozilla) mais a frente.
Strict, Transitional ou Frameset
Existem três tipos de DOCTYPEs que podemos usar em nossos documentos HTML. Strict, Transitional e Frameset. Qual a diferença entre eles e qual devemos usar?
O DOCTYPE Transitional é, como o nome diz, uma transição entre versões mais antigas do HTML e a versão mais nova, 4.01. Nele temos alguns elementos e atributos que definem apenas apresentação e não semântica (Leia meu texto sobre desenvolvimento em camadas) e devem, a rigor, ser eliminados de nossos documentos. Além disso, um DOCTYPE HTML 4.01 Transitional faz com que a maioria dos browsers trabalhe em modo de compatibilidade, o que não é nada desejável. Portanto, o DOCTYPE Transitional deve ser evitado a todo custo. Não use nunca.
Já o DOCTYPE Strict é uma evolução do Transitional, que elimina todos esses elementos e atributos meramente de apresentação e deixa apenas os elementos que realmente carregam consigo algum significado específico. Este é o DOCTYPE que devemos usar, sempre.
O Frameset serve apenas para o caso de você precisar usar frames nos seus documentos. Mas você não quer fazer isso, né? Se quiser, depois vou te dar alguns bons motivos pra tirar essa idéia da cabeça.
Comecei esse blog falando de HTTP, que é o que há de mais básico na web e que deveria correr naturalmente nas veias de todos que trabalham de alguma maneira com web. Estive pensando se deveria criar mais posts sobre o assunto, aprofundar um pouco, mas acho que ainda não é a hora.
É hora de falar de outra tecnologia que também tem precisa estar, entre um glóbulo vermelho e outro, em grande quantidade, na nossa corrente sangüínea.
Como sempre, vamos começar do começo. E, é claro, vamos por partes.
HTML é uma linguagem de marcação de texto. Mais especificamente, uma linguagem de marcação de hipertexto. Portanto, antes de começar a falar de HTML, vamos entender o que vem a ser uma linguagem de marcação.
Linguagens de marcação
Linguagens de marcação (markup languages em inglês), são linguagens que combinam texto com informações extras sobre o texto. Essa informação extra pode ser representada por diversos símbolos ou palavras-chave diferentes, dependendo da linguagem de marcação com que estivermos trabalhando.
No caso do HTML — e de outras linguagens da mesma classe, que são linguagens de marcação descritiva — a informação extra é representada pelo que chamamos de tags. Falaremos mais de tags daqui a pouco.
O importante é saber que essa informação extra (que vamos chamar daqui pra frente apenas de tags, por praticidade) serve para descrever ou dar significado à parte do texto que estiver marcada com ela. A isso chamamos semântica, que podemos dizer que é o conceito chave que precisamos absorver para entender de fato o funcionamento de uma linguagem de marcação.
Resumindo, uma linguagem de marcação descritiva de texto serve pura e simplesmente para dar significado especial a determinadas partes desse texto. Isso vai ficar mais claro mais a frente, acreditem em mim. Não mudem de canal, crianças.
SGML
SGML significa Standard Generalized Markup Language (Linguagem Padrão de Marcações Genéricas, em português) e podemos dizer que é a linguagem-mãe do HTML (e também do XML e de outras linguagens, como DocBook, por exemplo).
A SGML é o que podemos chamar de uma meta-linguagem, ou seja, uma linguagem destinada a criar outras linguagens. Não vamos nos aprofundar em SGML, não é o nosso foco. Apenas é importante saber que as regras que se aplicam ao HTML são derivadas da SGML. Inclusive o conceito de tags para descrever semanticamente o papel de determinado conteúdo dentro de um documento.
Tags
Podemos dizer, grosso modo, que tags são delimitadores de texto, que informam ao interpretador (um browser, por exemplo) como esse texto deve ser entendido.
A anatomia de uma tag é bem simples. Uma palavra (ou apenas uma letra) delimitada pelos caracteres ‘<’ e ‘>’.
Por exemplo, <p> é a tag usada para descrever parágrafos em HTML. <p> é uma tag.
Existem dois tipos de tag: de abertura e de fechamento. A tag de abertura deve vir imediatamente antes do texto a ser marcado e a tag de fechamento, imediatamente depois. A única diferença entre uma tag de abertura e uma de fechamento é que a de fechamento tem uma ‘/’ antes da letra ou palavra. Exemplo: a tag de fechamento de um parágrafo é </p>
Então, um parágrafo em HTML seria assim:
<p>Este é um parágrafo.</p>
Além do nome da tag (o ‘p’) e dos caracteres ‘<’, ‘>’ e ‘/’, uma tag pode conter atributos.
Um atributo é um modificador, ou melhor, uma informação a mais sobre a tag. Atributos são definidos por uma palavra-chave, um sinal de igual (‘=’) e um valor, entre aspas duplas ou simples.
Exemplo:
<p class="text">Este é um parágrafo com classe.</p>
Atributos podem ter valores pré-definidos ou valores livres. Ao longo dos posts vamos ver exemplos de ambos os casos e entender melhor como cada atributo funciona.
HTML, como qualquer linguagem baseada em SGML (excluindo o XML, que é uma meta-linguagem baseada no SGML, falamos disso um outro dia), tem a característica de ser simples para o desenvolvedor e complexa para o interpretador. Isso se deve a diversos fatores. Mas isso fica pra depois, nessa mesma hora, nesse mesmo canal.
Voltando à ativa depois de tanto tempo de inatividade, quero mostrar a vocês um exemplo comum de uso das camadas de conteúdo e apresentação. Um menu com imagens e rollover, mais acessível do que o normal e não muito complicado de se fazer.
O conceito é bastante simples: um DIV contendo uma lista não ordenada (UL), cujos itens são posicionados de maneira absoluta, funcionando mais ou menos como um mapa de imagens (MAP). O rollover é obtido mudando o posicionamento da imagem de fundo. No final, vou mostrar algumas modificações que podem ser usadas para tornar o menu mais acessível.
Vamos começar do começo, como sempre:
Código HTML básico
<div id="menu">
<ul>
<li><a href="#">Início</a></li>
<li><a href="#">Artigos</a></li>
<li><a href="#">Contato</a></li>
</ul>
</div>
O código acima é praticamente tudo que vamos precisar ter na camada de conteúdo. Bem simples, como deve ser. Veja o exemplo 1.
Posicionando o que tem que ser posicionado
<style type="text/css">
#menu{ position:relative; width:186px; height:35px; }
#menu ul{ list-style:none; }
#menu li{
position:absolute;
top:0;
height:35px;
border:1px solid;
}
#menu li a{
display:block;
width:100%;
height:100%;
top:0;
}
#um{ width:53px; left:0; }
#dois{ width:61px; left:53px; }
#tres{ width:72px; left:114px; }
</style>
<div id="menu">
<ul>
<li id="um"><a href="#">Início</a></li>
<li id="dois"><a href="#">Artigos</a></li>
<li id="tres"><a href="#">Contato</a></li>
</ul>
</div>
Adicionamos um ID para cada item da lista, para que suas posições e larguras possam ser definidos separadamente.
O DIV menu precisa ter posicionamento relativo, para “conter” seus filhos, que serão posicionados de maneira absoluta. (leia meu artigo sobre posicionamento com CSS)
Note que cada LI tem uma largura (width) e uma posição horizontal (left) diferentes. O cálculo é simples: o valor de left é sempre a largura do LI anterior somado ao valor de left deste.
Usamos uma borda apenas para ilustrar. Veja o resultado no exemplo 2.
Adicionando uma imagem de fundo
A imagem de fundo deve ser o menu inteiro. Algo mais ou menos como a imagem abaixo:

Esta imagem vai ser aplicada como fundo do DIV menu. E esta é a única mudança com relação ao exemplo anterior:
#menu{
position:relative;
width:186px;
height:35px;
background:url(img1.gif) no-repeat 0 0;
}
Veja o resultado no exemplo 3. Note que o texto está por cima da imagem. Vamos resolver isso.
Escondendo o texto
A forma mais simples de esconder o texto é usando a propriedade CSS text-indent com um valor negativo muito alto. Vamos usar -9999em. Isso faz com que o texto seja levado para a esquerda e fique fora do espaço visível.
Esta técnica tem sido muito usada para efeitos de image replacement, que é como chamamos os métodos usados para substituir texto por imagens, usando CSS.
Este método, usando text-indent negativo, é efetivo, porém tem o problema de não exibir conteúdo algum caso o browser tenha suporte a CSS ligado e suporte a imagens desligado. Esta é uma situação bem difícil de acontecer, mas nem por isso devemos deixar de nos preocupar. Vamos achar uma maneira de resolver este problema no último passo do tutorial.
O que muda no código:
#menu ul{
list-style:none;
text-indent:-9999em;
}
#menu li a{
display:block;
text-decoration:none;
width:100%;
height:100%;
top:0;
}
O text-indent negativo foi aplicado ao UL e colocamos um text-decoration:none no A, para evitar que apareça uma linha azul estranhíssima em algumas versões do IE.
Veja o resultado no exemplo 4.
Adicionando o efeito de rollover
Para obter o efeito de rollover (ou seja, alguma mudança ao se passar o mouse sobre o elemento), vamos mudar a imagem usada como fundo. Apenas duplicamos a imagem e mudamos alguma coisa em cada um do itens. Neste caso, mudei a cor do texto. Veja:

Mesmo a imagem tendo o dobro da altura da anterior, apenas a parte superior vai aparecer, já que nosso DIV tem uma altura fixa, em pixels.
Para o rollover, vamos usar a pseudo-classe :hover do A, e aplicar a imagem acima como fundo deste elemento, porém em posições diferentes para cada um deles. Veja:
#um a:hover{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover{
background:url(img2.gif) no-repeat -114px -35px;
}
O primeiro valor é a posição da imagem na horizontal (left) e o segundo, na vertical (top). Percebam que o primeiro valor é sempre igual ao left do LI que contém o A. Veja o exemplo 5.
Um pouco mais de acessibilidade
Lembra do que falei, lá em cima, sobre nada ser exibido caso tenhamos CSS habilitado e imagens desabilitadas? Pois bem, há uma solução. Mas, claro, não é de graça. Vamos ter que adicionar alguma coisa ao nosso código HTML.
<div id="menu">
<ul>
<li id="um"><a href="#"><span></span>Início</a></li>
<li id="dois"><a href="#"><span></span>Artigos</a></li>
<li id="tres"><a href="#"><span></span>Contato</a></li>
</ul>
</div>
Colocamos um SPAN vazio dentro de cada A. Alguns podem achar isso um pouco “sujo” e, na verdade, não deixa de ser. Porém, não perdemos nada de substancial com o uso destes elementos vazios, e vamos, no entanto, ganhar um pouco em termos de acessibilidade. Na minha opinião, vale a pena. Você decide se vale ou não para você.
Os referidos SPANs vão ser declarados como elementos de bloco e posicionados de maneira absoluta, de modo que fiquem “por cima” de seus pais (A). Vamos colocar uma imagem de fundo para cada SPAN (o mesmo valor usado nos :hovers, mas com posição vertical 0 ao invés de -35px). Veja:
#menu li a span{
display:block;
position:absolute;
width:100%;
height:100%;
top:0;
cursor:pointer;
}
#um a span{
background:url(img2.gif) no-repeat 0 0;
}
#dois a span{
background:url(img2.gif) no-repeat -53px 0;
}
#tres a span{
background:url(img2.gif) no-repeat -114px 0;
}
Percebam que tive que usar cursor:pointer para que o cursor padrão de ponteiro (aquela “mãozinha” que aparece quando você passa o mouse sobre um link) apareça no Internet Explorer.
Vejam o exemplo 6.
Rollover de novo
Vamos adicionar o efeito de rollover a esse nosso novo código.
#um a:hover span{
background:url(img2.gif) no-repeat 0 -35px;
}
#dois a:hover span{
background:url(img2.gif) no-repeat -53px -35px;
}
#tres a:hover span{
background:url(img2.gif) no-repeat -114px -35px;
}
Se você acompanhou bem até aqui, acho que não preciso explicar, né? Vejam o exemplo 7.
Consertando o rollover no IE
Os mais atentos com certeza notaram que ocorre um problema com o exemplo acima no Internet Explorer. Quando você passa o mouse sobre um link, ele muda de cor, mas não volta à cor original quando o cursor é movido para fora do elemento. Não me perguntem por que isso acontece, não faço a mínima idéia.
Passei alguns minutos tentando achar uma solução, e achei!
Por algum motivo, se colocarmos o z-index (que é o posicionamento no eixo Z, ou seja, serve para colocar um elemento “por cima” de outro) do a:hover para um valor alto (vou usar 1000, que é o valor máximo), tudo passa a funcionar perfeitamente no IE, e continua funcionando normalmente nos outros browsers.
#menu ul li a:hover{
z-index:1000;
}
Simples assim. Porém, notem que o seletor desta regra deve ser mais específico que o do :hover. Vou falar sobre especificidade um dia desses. Por agora, tente adicionar apenas um ID a mais no seletor (no caso #menu) e especificar cada um dos elementos, na ordem (no caso ul li). Isso vai funcionar.
Confira o resultado final.
O código foi testado e aprovado nos seguintes browsers:
- Firefox 1.5
- Opera 9
- Internet Explorer 6
- Swift (um “safari para windows”, muito experimental ainda, portanto não posso garantir que o resultado seja o mesmo no safari do Mac OS X).
Se algum de vocês puder testar em outros browsers e me dizer se funciona, agradeço.
***
Espero que este exemplo seja de alguma utilidade para vocês. Dúvidas, sugestões e reclamações são muito bem vindas.
Vamos então aos posts com exemplos de códigos simples, mostrando o uso de uma ou mais das três camadas de desenvolvimento apresentadas nos dois posts anteriores.
Antes de começar, devo deixar claro que praticamente qualquer funcionalidade que você precise, seja em HTML, CSS ou JavaScript geralmente está a apenas uma “googlada” de distância. Se você tem um problema é muito provável que alguém já tenha tido o mesmo problema e a chance de que esse alguém já tenha resolvido e blogado sobre a solução também é muito grande.
O código feito aqui não se baseia em nenhum outro diretamente. Mas nada impede que eu use, inconscientemente (ou conscientemente, vai dizer) algo que eu já tenha visto por aí e tenha ficado registrado na caixola.
Vamos ao que interessa. Neste texto vamos fazer um título editável, ou seja, um título normal que, ao ser clicado se transforma em um campo de texto (INPUT) que ao perder o foco salva o novo valor e volta a ser um título novamente.
Começando pelo começo
A primeira coisa que precisamos é de uma página HTML com um título, no caso um H1, como pode ser visto no exemplo 1.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Título editável com JavaScript</title>
<style type="text/css">
h1 {
font:normal 2.4em/1.6 georgia, "times new roman", "bitstream vera serif", times, serif;
color:#900;
}
</style>
<script type="text/javascript">
</script>
</head>
<body>
<h1>Edite este título</h1>
</body>
</html>
Um Título simples, com um toquezinho de CSS só para definir a fonte e a cor, pra não ficar tosco demais.
Note que o CSS e o JavaScript vão ser colocados dentro do próprio arquivo HTML, apenas para facilitar o estudo. No “mundo real” o ideal é colocá-los em arquivos separados.
Fazendo o título parecer editável
Precisamos agora dar alguma dica ao usuário de que, se clicado, o título pode ser editado.
Uma mudança na cor de fundo em conjunto com um texto explicativo no atributo TITLE do H1 me parecem ser suficientes. Além disso, vamos colocar um SPAN dentro do H1. Isso porque como o H1 é um elemento de bloco, ocupa por padrão 100% do espaço horizontal disponível. Para mudar isso poderíamos usar a propriedade CSS float ou definir uma largura específica para o H1. No caso do float, seria necessário definir a propriedade clear para o elemento logo abaixo do H1. Usar uma largura fixa não seria muito inteligente, pois o texto digitado pode ser maior que esse espaço. Portanto, fico com o SPAN.
Nesse ponto temos algo parecido com o exemplo 2.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Título editável com JavaScript</title>
<style type="text/css">
h1 {
font:normal 2.4em/1.6 georgia, "times new roman", "bitstream vera serif", times, serif;
color:#900;
}
h1 span:hover{
background:#f5f5f5;
}
</style>
<script type="text/javascript">
</script>
</head>
<body>
<h1><span title="Clique para editar o texto">Edite este título</span></h1>
</body>
</html>
Você deve ter percebido que o exemplo 2 não funciona muito bem no Internet Explorer. Isso acontece porque o IE não tem suporte à pseudo-class :hover em elementos senão o A. Portanto, para obter esse efeito precisaremos de uma pitadinha de JavaScript.
Veja o exemplo 3. Perceba que coloquei o código todo dentro de uma função atribuída ao evento onload do objeto window, ou seja, o script será executado assim que o documento terminar de ser carregado pelo browser. Essa não é a melhor forma de fazer as coisas, mas por agora nos serve muito bem. Mais à frente veremos formas mais interessantes de “inicializar” nossos scripts.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Título editável com JavaScript</title>
<style type="text/css">
h1 {
font:normal 2.4em/1.6 georgia, "times new roman", "bitstream vera serif", times, serif;
color:#900;
}
</style>
<script type="text/javascript">
window.onload = function(){
var title = document.getElementsByTagName('h1')[0];
var span = title.firstChild;
span.onmouseover = function(){
this.title = 'Clique para editar o texto';
this.style.background = '#f5f5f5';
}
span.onmouseout = function(){
this.title = '';
this.style.background = '';
}
}
</script>
</head>
<body>
<h1><span>Edite este título</span></h1>
</body>
</html>
Pense comigo. O título só será editável caso o browser tenha suporte a JavaScript, portanto é melhor que tanto a cor de fundo ao passar o mouse quanto o TITLE só existam quando o suporte estiver presente.
Explicando o script: na linha var title = document.getElementsByTagName('h1')[0]; colocamos na variável title uma referência para o primeiro elemento definido pela tag H1 no documento.
Na linha seguinte, var span = title.firstChild; pegamos o primeiro filho (firstChild) do H1 — que, no caso, é o SPAN, e jogamos para a variável span.
Nas linhas seguintes definimos, no evento onmouseover do SPAN, seu título e cor de fundo e no onmouseout limpamos esses valores. Simples, não? Pois bem, avancemos.
Criando um INPUT para edição do texto
Agora precisamos que, ao clicar no título, este se transforme em um INPUT para permitir a edição do texto.
Para isso vamos usar o evento onclick do nosso SPAN, como pode ser visto no exemplo 4.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Título editável com JavaScript</title>
<style type="text/css">
h1 {
font:normal 2.4em/1.6 georgia, "times new roman", "bitstream vera serif", times, serif;
color:#900;
}
</style>
<script type="text/javascript">
window.onload = function(){
function editTitle(){
var title = document.getElementsByTagName('h1')[0];
var span = title.firstChild;
span.onmouseover = function(){
this.title = 'Clique para editar o texto';
this.style.background = '#f5f5f5';
}
span.onmouseout = function(){
this.title = '';
this.style.background = '';
}
span.onclick = function(){
var textoAtual = this.firstChild.nodeValue;
var input = '<input type="text" value="'+textoAtual+'">';
this.innerHTML = input;
var field = this.firstChild;
this.onclick = null;
this.onmouseover = null;
field.focus();
field.select();
field.onblur = function(){
this.parentNode.innerHTML = this.value;
editTitle();
}
}
}
editTitle();
}
</script>
</head>
<body>
<h1><span>Edite este título</span></h1>
</body>
</html>
Note que o código dessa vez foi colocado dentro de uma função, editTitle() que é chamada logo após a sua definição. Já explico porque isso foi necessário. Primeiro vamos entender como o esquema funciona.
var textoAtual = this.firstChild.nodeValue; pega o texto contido no SPAN e joga para a variável textoAtual. Perceba o uso de firstChild. Abra o DOM Inspector e vá até o SPAN. Veja que dentro desse SPAN há um elemento, que é um textNode, representado por #text. Esse textNode é o primeiro filho (firstChild) do nosso SPAN e o seu valor (nodeValue) é o texto em si, no caso “Edite este texto”.
Logo abaixo criamos uma string, que é um código HTML representando um INPUT, já com o VALUE definido com o valor de textoAtual. Feito isso, colocamos essa string no innerHTML do SPAN. innerHTML é o conteúdo HTML presente dentro do elemento em questão.
Nesse momento, o input passa a ser o firstChild do SPAN. Guardamos uma referência para ele na variável field.
Agora limpamos os eventos onclick e onmouseover do SPAN, usando this.onclick = null; e this.onmouseover = null; (retire estas duas linhas do código e teste para entender o porquê disso) e depois jogamos o foco para o INPUT e selecionamos o texto nele contido.
O próximo passo é atualizar o valor do nosso SPAN (que é o pai [parentNode] do INPUT) no evento onblur (perda de foco) do INPUT e chamar a própria função editTitle() para garantir que o código continuará funcionando. Experimente retirar a chamada para a função editTitle() de field.onblur e teste para entender melhor.
[update]
Atualizando o valor do título ao pressionar ENTER
Sugeri que os leitores fizessem, como “dever de casa”, com que o valor do título fosse atualizado ao pressionarmos a tecla ENTER.
O’Marin fez e postou nos comentários, mas o código dele não funciona no Internet Explorer. Os outros browsers (pelo menos os gecko-based e o Opera) capturam o evento que acontece ao pressionarmos uma tecla e o joga na variável usada como parâmetro da função atribuida ao evento onkeypress. Já o IE captura esse evento e atribui a um objeto, o window.event.
Precisamos apenas checar se esse objeto existe e, em caso positivo, usá-lo para pegar o código da tecla pressionada. Caso não exista, usamos a variável do parâmetro (que, no meu exemplo, vai se chamar e).
Outra coisa que O’Marin faz e que poderia ser feito de uma forma mais adequada é repetir o código que já está sendo usado no evento onblur dentro do evento onkeypress. Podemos reutilizar o código já existente chamando o método blur() do objeto em questão, já que, ao pressionar enter, é interessante tirar o foco do INPUT. Veja no exemplo 5.
field.onblur = function(){
this.parentNode.innerHTML = this.value;
editTitle();
}
field.onkeypress = function(e){
var keynum;
if(window.event) // IE
keynum = window.event.keyCode;
else if(e.keyCode) // Netscape/Firefox/Opera
keynum = e.keyCode;
if (keynum == 13) this.blur();
}
Esse exemplo foi testado e funciona no IE, Firefox e Opera. Concordam comigo ou têm alguma solução melhor?
[/update]
Conclusão
É claro que para esse código se transformar em alguma coisa realmente útil é necessário guardar o valor do texto editado em algum lugar onde este persista (um banco de dados, por exemplo), mas isso fica para um outro post.
E, como dever de casa (hehe), tente fazer com que o texto seja atualizado quando o usuário pressionar ENTER. Quem conseguir, poste a solução nos comentários. Caso ninguém consiga, colocarei o código aqui, em um update do post.
Espero ter sido claro e que isto seja de utilidade para vocês pelo menos para ajudar a entender um pouquinho mais a camada de comportamento. Comentários são muito bem vindos.
No post anterior falei sobre desenvolvimento em camadas e apresentei a vocês as camadas de conteúdo e apresentação.
Ficou faltando a camada de comportamento. Vamos a ela então.
A camada de comportamento deve ser encarada como uma camada extra no desenvolvimento de uma página para a web. Nessa camada, usamos uma linguagem de script (JavaScript) junto com o DOM (Document Object Model) para modificar o comportamento dos elementos presentes na camada de conteúdo.
Digo que essa camada deve ser encarada como extra porque é importante que seu site ou aplicação funcione perfeitamente na ausência dessa camada (ou do suporte a ela).
O DOM
O DOM é um modelo de dados usado pelos user-agents para montar uma representação do código de uma página (seja ela escrita em HTML, XHTML ou XML) após sua renderização. É mais ou menos como uma árvore. Você pode usar o DOM Inspector do Firefox para dar uma olhada na estrutura dessa árvore. Já falei sobre o DOM Inspector e outras ferramentas legais para desenvolvedores no meu blog.
A partir da DOM API (que é algo como uma coleção de métodos para manipular os elementos no DOM) podemos selecionar elementos ou grupos de elementos e seus atributos e executar diversas funções com eles, inclusive criar ou remover elementos.
No caso do desenvolvimento da camada de comportamento de um site, usamos a DOM API presente no JavaScript, que é a linguagem de script existente em todos os browsers modernos.
Em geral, a maior parte do trabalho que se tem para desenvolver essa camada reside na manipulação do DOM.
São exemplos dos métodos existentes na DOM API:
- document.getElementById(id)
- Seleciona um elemento a partir do valor de seu atributo ID. É a maneira mais simples de se acessar um elemento no DOM.
Digamos que você tenha um DIV com ID “conteudo”.var conteudo = document.getElementById('conteudo')vai fazer com que a variável conteudo contenha uma referência para o referido DIV. Manipule a variável conteudo e as alterações serão feitas no DIV. - document.getElementsByTagName(tag)
- Seleciona um conjunto de elementos que são definidos pela tag “tag”.
Exemplo:var uls = document.getElementsByTagName('ul')cria em uls um array onde cada item é uma referência para um elemento UL dentro do documento.
uls[0]seria, nesse caso, uma referência para a primeira UL presente no documento.
Esses são, com certeza, os dois métodos que serão mais usados em qualquer script que você venha a desenvolver. Existem outros tantos que não vou listar aqui para não tornar o post extenso demais e até mesmo porque esse não é o intuito do texto. Uma ótima referência de métodos da DOM API pode ser encontrada na referência de DOM do Mozilla Developer Center. Apenas tenha em mente que essa referência é específica para os browsers baseados no engine Gecko (Mozilla, Firefox, Netscape), mas praticamente todos os métodos lá descritos funcionam também nos outros browsers igualmente modernos.
Existem milhões de coisas que podem ser feita usando a dupla DOM/JavaScript. Geralmente, usamos a camada de comportamento para melhorar de alguma forma a experiência do usuário ao utilizar uma página web.
Não vou me estender mais no assunto. Leiam o que o Élcio escreveu sobre o assunto. O texto dele é bem explicativo e cita diversas fontes que podem ser usadas como referência para o aprendizado das tecnologias envolvidas no desenvolvimento da camada de comportamento.
Nota: Relendo o texto percebo que está muito aquém do que eu pretendia escrever. É difícil passar o conceito de camada de comportamento sem exemplificar, sem tornar o texto técnico.
Acho que a melhor coisa a fazer é publicar posts menores, com exemplos de código explicados, sobre cada camada. O que vocês acham?








