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

Alvaro Freitas disse:

Caro Ramon Bispo, Ratifico que a excepcional ferramenta criada por você voltou a funcionar. Parabéns pela sua criatividade e iniciativa próprias de ...

Mário Sérgio disse:

Gostei das várias abordagens nesse poste. Fala bastante da realidade do dia-dia do Webdesigner e dos desenvolvedores....

Jayro Motta disse:

Parabéns, Ramon pela incrível e tão oportuna iniciativa que, além do mais, é free! Fiz testes e notei que se preocupou com o que muda na nova ortog...

Nobuo disse:

Haaa, muito bom Page! To aprendendo alguma coisa disso na faculdade, muito interessante!...