BreakDance na ZonaJ

Num blog em que o texto das várias entradas tende a ser extenso (como este), a página principal começa rapidamente a ter um comprimento considerável.
Quando se pretende consultar uma entrada mais antiga só temos duas hipóteses:

  • se

    guimos o link permanente para a entrada (caixa ‘Posts Recentes’) e depois fazemos ‘back’ no browser;

  • damos ao dedo a fazer scroll na página até que a entrada fique visível.

Uma forma interessante de resolver este problema seria ter uma opção de toggle do texto das entradas, ou seja, ter uma opção para mostrar ou esconder o texto dos posts por escolha do utilizador.

Estava a matutar sobre isto enquanto admirava os tons campestres desta página e pensei que não era má ideia pôr a solução em prática.

Um requisito importante é que o teria de fazer sem alterar efectivamente a página (só para não estar a chatear o Administrador do blog durante o fim-de-semana :-) ).

Outro é que o código teria de ser suficiente pequeno para poder ser postado aqui.

Era definitivamente um bom desafio para por à prova o jQuery.

Precisava de quatro operações para concretizar as alterações:

  1. esconder inicialmente o texto das entradas e os links para tags e comentários mas não o titulo ou a informação dos autores;
  2. acrescentar à frente do nome do autor um link para permitir mostrar ou esconder o texto;
  3. associar ao evento click do link uma função para concretizar a opção do utilizador;
  4. desenvolver a função;

Usei o Firebug para analisar a estrutura do DOM da página.
Cada entrada tem uma estrutura fixa:

  1. um <h2> com o link para o titulo;
  2. um <h4> com a data do post e a identificação do autor;
  3. um <div> com a class ‘entry’ com o texto;
  4. um <p> com a class ‘tagged’ com links para as tags e comentários

Portanto, para concretizar a primeira operação só precisava de esconder os elementos com as classes ‘entry’ e ‘tagged’ que em jQuery se traduz como:
$('.entry, .tagged').hide();

Para a concretizar segunda operação acrescentei um link à frente do nome do autor, ou seja, de todos os <h4>s precedidos por <h2>s, ou em jQuery:
$('h2 ~ h4').append('<a href="javascript:void(0)" class="entryToggler">(Mostrar)</a>');

Para a terceira opção e visto que associei os links criados à class entryTogger, basta associar uma função ao evento onclick de todos os

elementos com esta classe ou em jQuery:
$('.entryToggler').click(toggleEntry);

Falta só desenvolver a função toggleEntry.

Uma vez que esta função tem acesso ao elemento anchor seleccionado pelo utilizador (this), podia usá-lo como referência para:

  1. verificar o estado da entrada a partir do texto:
    var isHidden = $(this).text().search('Mostrar')!=-1;
  2. seleccionar os elementos correspondentes ao texto e aos links para as tags e comentários:
    var x=$(this).parent().next(); x = x.add(x.next());
  3. mostrar ou esconder os elementos seleccionados:
    isHidden ? x.slideDown('slow') : x.slideUp('slow');
  4. alterar o texto do link para ficar de acordo com a operação:
    isHidden ? $(this).text('(Esconder)') : $(this).text('(Mostrar)');

e estava feito!

Como podem testar o código? É fácil:
abram a página principal do blog. (pessoal do rss, tem mesmo que ser na página principal)

Se estiverem a usar o Firebug podem copiar o código completo para a consola e executarem-no:

var toggleEntry = function(){	
	var isHidden = $(this).text().search('Mostrar')!=-1;
	var x=$(this).parent().next();
	x = x.add(x.next());
	isHidden ? x.slideDown('slow') : x.slideUp('slow');	
	isHidden ? $(this).text('(Esconder)') : $(this).text('(Mostrar)');		
};
$('.entry, .tagged').hide();
$('h2 ~ h4').append('<a href="javascript:void(0)" class="entryToggler">(Mostrar)</a>');
$('.entryToggler').click(toggleEntry);

Para os outros casos, escrevi o código todo numa só linha que podem copiar para a caixa de endereço do browser (substituindo o http://www.zonaj.org):

javascript:var toggleEntry = function(){var isHidden = $(this).text().search('Mostrar')!=-1;var x=$(this).parent().next();x = x.add(x.next());isHidden ? x.slideDown('slow') : x.slideUp('slow');isHidden ? $(this).text('(Esconder)') : $(this).text('(Mostrar)');};$('.entry, .tagged').hide();$('h2 ~ h4').append('<a href="javascript:void(0)" class="entryToggler">(Mostrar)</a>');$('.entryToggler').click(toggleEntry);void(0);

Testado com FF2, IE7 e Opera9.

É claro que tive a vantagem de não me ter de preocupar em importar o script de jQuery porque a própria página já o faz.
Caso estivesse a alterar o DOM de uma página que não use jQuery, podia fazer o mesmo tipo de alterações usando o jQuerify.

Nota 1:
Para deixar a primeira entrada sem alterações basta alterar a linha
$('.entry, .tagged').hide();
para
$('.entry, .tagged').not(':first').hide();
e a linha
$('h2 ~ h4').append('<a href="javascript:void(0)" class="entryToggler">(Mostrar)</a>');
para
$('h2 ~ h4').not(':first').append('<a href="javascript:void(0)" class="entryToggler">(Mostrar)</a>');

Nota 2:
Para remover a irritante ‘caixa picotada’ à volta do link quando este fica activo, acrescentar como ultima linha da função:
$(this).blur();

Nota 3:
O código final tem cerca de 10 (!) linhas e repeti-o 3 vezes neste post.

Nota 4:
Para ter de volta a página original basta fazer reload no browser (mesmo tendo alterado a linha de endereço).

2 thoughts on “BreakDance na ZonaJ”

  1. Cada vez mais me consegues convencer que o jQuery é uma das melhores invenções do mundo, atrás do Compal de pêra.
    Existe uma opção do WordPress que permite mostrar apenas o início de cada post, tal como ocorre se se efectuar uma pesquisa no site. Não considerei muito importante na altura mas também ainda estão muitas coisas por fazer aqui, entre outras coisas mostrar posts relacionados.

    De qualquer forma, o post é um bom exemplo do poder do jQuery. Muito bom.

Leave a Reply to Ruben Badaró Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>