Nem sempre uma paginação é a melhor maneira de limitar o conteúdo exibido em um site. Às vezes pode ser bem chato ficar indo de página em página procurando alguma coisa, você acaba se perdendo. O Twitter é um bom exemplo. Na interface do aplicativo, o botão “load more” faz as vezes de uma paginação e carrega a próxima sequência de tweets em sua timeline.
Neste artigo, além do link para carregar os próximos conteúdos, veremos também uma abordagem mais dinâmica onde o conteúdo é carregado assim que o scroll atinge o final da página.
E por falar em Twitter, nossos exemplos utilizarão sua API para carregar os dados de exemplo, mas é claro que eles funcionam com qualquer script que forneça os dados em JSON.
Carregando tweets
A API do Twitter oferece a possibilidade de baixar os últimos tweets de um usuário utilizando apenas JavaScript. A API oferece opção de saída em vários formatos, entre eles XML, Atom e JSON (formato utilizado em nosso exemplo).
Na nossa chamada ajax passamos ainda o nome da conta no Twitter e o número da página dos tweets.
var usuario = 'tableless'; var formato = 'json'; var url = 'https://api.twitter.com/1/statuses/user_timeline.'+formato+"?callback=?"; $.getJSON(url, {screen_name:usuario, page:pagina}, function(tweets){ // nosso código });
O retorno, o objeto com os tweets:
[ { "favorited":false, "text":"http:\/\/bit.ly\/esqJUw Trabalha com TI?\u00a0N\u00e3o importa seu campo de atua\u00e7\u00e3o, confira essa oportunidade da Intel\u00a0 #ad", "retweet_count":0, "in_reply_to_screen_name":null, "in_reply_to_status_id_str":null, "place":null, "contributors":null, "retweeted":false, "in_reply_to_user_id":null ... } ]
Load more
Vamos então ao nosso primeiro exemplo, o botão para carregar mais tweets. Ao acessar a página são carregados automaticamente 12 tweets e os novos tweets só são carregados quando o usuário clica no link.
O HTML, que também será utilizado em nosso segundo exemplo, é esse:
<ul id="lista-tweets"></ul> <a href="#" id="carrega-tweets">Mais!</a>
O primeiro passo é associar a função para exibir mais tweets ao elemento “#carrega-tweets”, impedindo também o funcionamento padrão do clique (que nesse caso seria ir para o link “#”) com o método preventDefault.
$('#carrega-tweets').click(function(e){ retorna_tweets($(this).data('pagina')); e.preventDefault(); });
Ao clicar no link, nosso site executa a funcão retorna_tweets, recebendo como parâmetro a página dos tweets a serem carregados. A página fica armazenada no próprio elemento e é incrementada toda vez que ocorre um clique (o método data merece um outro artigo, por isso não vou falar muito sobre ele aqui).
function retorna_tweets(pagina){ $('#carrega-tweets').hide(); $('#lista-tweets').append('
A função retorna_tweets segue o seguinte fluxo:
Oculta o link de carregamento para evitar que a ação seja executada mais de uma vez ao mesmo tempo;
$(‘#carrega-tweets’).hide();
Adiciona um ítem à lista de tweets para informar ao usuário que o conteúdo está sendo carregado;
$(‘#lista-tweets’).append(’
Através do método getJSON, recebe a lista de tweets da conta informada (no nosso caso, a conta do Tableless);
$.getJSON(url, {screen_name:screen_name, page:pagina}, function(tweets){
Quando a API termina de enviar os dados pra gente, escondemos e removemos o loader e ao mesmo tempo adicionamos ítems à lista com o texto de cada tweet;
$(‘.carregando’).fadeOut(function(){ for(x in tweets) $(‘#lista-tweets’).append(’
- E, finalmente, incrementamos o número da página atual no link e voltamos a exibí-lo.
$(‘#carrega-tweets’).data(‘pagina’, pagina + 1).fadeIn();
Infinite Scrolling
Outra maneira interessante é carregar o conteúdo quando o scroll atinge o final da página. Essa abordagem é um pouco mais agressiva já que o usuário não tem total controle sobre o conteúdo que deseja ver. Por outro lado, ele não precisa se preocupar em clicar em nada para exibir mais conteúdo.
var ajax = ""; $(function(){ retorna_tweets(1); $('body').data('pagina', 1); inicializa_scroll(); }); function inicializa_scroll(){ $(window).scroll(function() { if(($(window).scrollTop() + $(window).height() + 20) >= $(document).height()) { $(window).unbind('scroll'); ajax.abort(); retorna_tweets($('body').data('pagina')); } }); }
Nesse caso, como não possuímos um link, armazenamos o número da página a ser carregada no elemento body e iniciamos, é claro, o carregamento com a página 1. A função inicializa_scroll é responsável por associar o evento scroll da janela com nosso carregamento de tweets.
Dois detalhes importantes de usabilidade: quando o carregamento é executado nós removemos a associação do método scroll da janela para evitar duplicidades ($(window).unbind(‘scroll’)) e, além disso, interrompemos alguma chamada anterior (ajax.abort();). A variável global ajax foi criada no início do nosso javascript e ela vai receber a chamada ajax na função retorna_tweets.
Vamos analisar agora a comparação do scroll com a altura do documento:
$(window).scrollTop() + $(window).height() + 20) >= $(document).height()
O método scrollTop retorna a altura da parte oculta da página, que está acima da parte atual, acima do scroll. Já a chamada $(window).height() retorna a altura do viewport, da parte visível da página. A soma dos dois, quando o scroll está no final da página, resulta em $(document).height(), que é a altura total do documento. Alguns navegadores apresentam diferenças mínimas nesses valores, entre 1 e 5px. Por isso o adicionamos 20 pixels para uma “margem de erro”.
Pra finalizar, o método retorna_tweets sofreu algumas alterações com relação ao nosso primeiro exemplo. A primeira é a incrementação do número da página nos dados do elemento body e não em um link. Também armazenamos nossa chamada getJSON na variável ajax, conforme citado anteriormente. E, ao invés de exibir novamente o link, associamos novamente a função retorna_tweets ao scroll da janela através do método inicializa_scroll.
function retorna_tweets(pagina){ $('#lista-tweets').append('