Sep42006

Mostrar-esconder conteúdo via DOM

Show-hide content with DOM

Um dos requisitos que declarei para o meu site foi a possibilidade de inserir conteúdo em outras línguas para as minhas postagens, em especial em inglês. Depois de alguns estudos cheguei à estrutura que desejava e desenvolvi um script em DOM para implementá-la. Como este não era um requisito de prioridade alta, deixei sua implementação para uma data futura. Eis que esta data chegou!

O conceito do script é simples: defini uma classe para todos os elementos (tags) que eu gostaria de inserir em inglês e fiz uma função em javascript para localizar todas as instâncias desta e escondê-la. Clicando em um link específico, as áreas são apresentadas. Clicando novamente no mesmo link, as áreas são escondidas.

Exemplo escondido:

This is an example of show-hide english content on <p> element

  • This is a list with english content
  • Line example
  • Line example

This is an <blockquote> element with english content.

Definindo os recursos da solução

O primeiro passo foi definir um link para esconder e mostrar as áreas. Inseri um ID para este link para poder trabalhá-lo via script.

  1. <a href="#" id="showHideTextNode"></a>

Não inseri nenhum conteúdo no link para poder manipulá-lo via script, trocando o texto, via innerHTML, de acordo com o clique efetuado ([+] Show english content para mostrar o conteúdo e [-] Hide english content para esconder o conteúdo).

Após, apenas defini uma classe para cada elemento que tivesse conteúdo em inglês. A classe foi chamada de lang-eng.

Manipulando a classe lang-eng via javascript

O primeiro passo foi definir um Array para todos os elementos que poderiam receber a classe lang-eng.

  1. var arrEls = new Array(”h1″,”h2″,”h3″,”h4″,”h5″,”h6″,”p”,”span”,”ul”,”blockquote”)

Após, foi preciso apenas uma função para localizar a classe lang-eng e efetuar as alterações nas páginas em que ela foi instanciada. Utilizei como base o script getElementByClass do Dustin Diaz. A partir daí, otimizei o script para chegar ao resultado que gostaria.

  1. function getTextNodeByClassName(searchClass,tag,eventNode) {
  2.  
  3. var els = document.getElementsByTagName(tag);
  4. var pattern = new RegExp("\\b"+searchClass+"\\b");
  5.  
  6. var idLink = 'showHideTextNode';
  7. var messageShow = '[+] Show english content';
  8. var messageHide = '[-] Hide english content';
  9.  
  10. var linkTextNode = document.getElementById(idLink);
  11.  
  12. for (i = 0; i < els.length; i++) {
  13. if ( pattern.test(els[i].className) ) {
  14. if (eventNode == 'hide') {
  15. linkTextNode.innerHTML = messageShow;
  16. linkTextNode.className = "link-show";
  17. linkTextNode.onclick = function() {
  18. for (j = 0; j < arrEls.length; j++) {
  19. getTextNodeByClassName('lang-eng',arrEls[j],'show');
  20. }
  21. };
  22. els[i].style.display = 'none';
  23. } else if (eventNode == 'show') {
  24. linkTextNode.innerHTML = messageHide;
  25. linkTextNode.className = "link-hide";
  26. linkTextNode.onclick = function() {
  27. for (j = 0; j < arrEls.length; j++) {
  28. getTextNodeByClassName('lang-eng',arrEls[j],'hide');
  29. }
  30. };
  31. els[i].style.display = 'block';
  32. }
  33. }
  34. }
  35. }

Por fim, inseri uma função para esconder todos os elementos declarados com a classe lang-eng. Esta função é inicializada por um addLoadEvent.

  1. function init_langEngNode() {
  2. if (!document.getElementsByTagName) return
  3. for (j = 0; j < arrEls.length; j++) {
  4. getTextNodeByClassName('lang-eng',arrEls[j],'hide');
  5. }
  6. }
  7.  
  8. add_event(init_langEngNode);

Como tudo funciona

Pegando todas as tags inseridas como parâmetro e selecionando apenas a classe desejada para estas tags. Numa tag com class="lang-eng alignleft", por exemplo, apenas a lang-left seria selecionada.

  1. function getTextNodeByClassName(searchClass,tag,eventNode) {
  2.  
  3. var els = document.getElementsByTagName(tag);
  4. var pattern = new RegExp("\\b"+searchClass+"\\b");

Eu poderia setar "*" como tag para pegar todas as tags na página (vide linha "var els = document.getElementsByTagName(tag);"), inutilizando a necessidade de criação do Array de elementos, porém esta estrutura tiraria o controle que eu teria sobre os elementos que eu efetivamente gostaria de esconder.

O bom da história é que praticamente toda a aplicabilidade da solução está no script, portanto qualquer alteração futura fica totalmente mais prática. Minhas intenções estavam totalmente voltadas na manipulação do mínimo possível de marcação e trabalhar diretamente no javascript.

Continuando...

Definindo o ID para o link de manipulação e suas mensagens.

  1. var idLink = 'showHideTextNode';
  2. var messageShow = '[+] Show english content';
  3. var messageHide = '[-] Hide english content';

Pegando o ID inserido no link da página.

  1. var linkTextNode = document.getElementById(idLink);

Para os elementos encontrados, testar se cada um deles tem a classe escolhida como parâmetro.

  1. for (i = 0; i < els.length; i++) {
  2. if ( pattern.test(els[i].className) ) {

Foram definidos dois parâmetros para manipular as tags: show para mostrar os conteúdos e hide para escondê-los. Uma estrutura de if foi criada para testar em qual status a página está. Caso o evento seja hide o link de manipulação recebe a mensagem [+] Show english content. Caso seja show, recebe a mensagem [-] Hide english content.

Para o evento onclick do link é inserida uma função para voltar à mesma função e mostrar ou esconder o conteúdo. A forma de esconder é simples: o elemento encontrado recebe como atributo display o valor "none" (els[i].style.display = 'none';). Para mostrar, o atributo display recebe o valor "block" (els[i].style.display = 'block';).

  1. if (eventNode == 'hide') {
  2. linkTextNode.innerHTML = messageShow;
  3. linkTextNode.className = "link-show";
  4. linkTextNode.onclick = function() {
  5. for (j = 0; j < arrEls.length; j++) {
  6. getTextNodeByClassName('lang-eng',arrEls[j],'show');
  7. }
  8. };
  9. els[i].style.display = 'none';
  10. } else if (eventNode == 'show') {
  11. linkTextNode.innerHTML = messageHide;
  12. linkTextNode.className = "link-hide";
  13. linkTextNode.onclick = function() {
  14. for (j = 0; j < arrEls.length; j++) {
  15. getTextNodeByClassName('lang-eng',arrEls[j],'hide');
  16. }
  17. };
  18. els[i].style.display = 'block';
  19. }
  20. }
  21. }
  22. }

O último passo foi estilizar a classe lang-eng para separar as áreas apresentadas (português/ inglês), senão ficaria tudo uma coisa só, visualmente.

Esta solução pode ser utilizada em vários outros contextos. Basta ter criatividade. ;)

Atualização 2006-11-06: Versão 2.0 concluída, ver: Mostrar-esconder conteúdo via DOM V.2

3 respostas para “Mostrar-esconder conteúdo via DOM”

  • Rodrigo

    Rodrigo - 10/09/08 às 7:01 am

    Bom,
    A questão é a seguinte…
    Eu ainda não testei o código fornecido aqui, porém tive uma dúvida.

    Você passou a seguinte codificação para esconder e mostra as páginas:

    Nete caso, para mostra e esconder o centeúdo que eu quero o código ficaria assim?
    # MEU CONTEUDO PARA MOSTRAR E ESCONDER

    Essa é minha única duvida…
    o resto consegui entender

  • Rodrigo

    Rodrigo - 10/09/08 às 7:03 am

    Corrigindo**

    Bom,
    A questão é a seguinte…
    Eu ainda não testei o código fornecido aqui, porém tive uma dúvida.

    Você passou a seguinte codificação para esconder e mostra as páginas:

    Nete caso, para mostra e esconder o centeúdo que eu quero o código ficaria assim?
    MEU CONTEUDO PARA MOSTRAR E ESCONDER

    Essa é minha única duvida…
    o resto consegui entender

  • RamonPage

    RamonPage - 13/09/08 às 1:55 pm

    Olá Rodrigo,

    para indicar quais as tags devem ser escondidas/mostradas, utilize a classe “lang-en” em cada uma delas.

    Ex.: <h3 class="lang-en" lang="en">Show-hide content with DOM</h3>

    Dêuma olhada na atualização deste script:
    http://ramonpage.com/2006/11/06/mostrar-esconder-conteudo-via-dom-v2/

Poste um comentário




Você pode utilizar as seguintes tags para formatação: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Oscomentários

Comentários diversos dos visitantes

Sylvestre disse:

Ramon, Te passei um e-mail cara! Responde ae. Abraço, Sylvestre....

RamonPage disse:

@Sandra, não encare como um abuso. Lo...

Karina disse:

Bakaaaaaaaana!...

warez-vip disse:

He sits at his chair, one of those faggy ball chairs, crosses his legs and turns toward his Macintosh. "Come, lovely. Let me show you how to open an e...

RamonPage disse:

@Frederico, o site...

Quemsou

Uma prévia de quem é RamonPage

Avatar RamonPage

Meu nome é Ramon Bispo. Sou web developer/ designer e natural do Rio de Janeiro, Brasil. Saiba mais sobre mim…