9 de agosto de 2010

Carregando conteúdo dinamicamente enquanto move a barra de rolagem

Sites como o facebook e orkut usam um efeito muito interessante de carregamento de conteúdo de acordo com a posição da barra de rolagem. O site carrega apenas uma parte dos dados e quando o usuário vai descendo a barra de rolagem o site se encarrega de pegar mais dados no servidor para exibir.

O efeito é simples de fazer e muito útil, pois o servidor não precisará carregar todos os dados de uma só vez. Para fazer isso utilizaremos o JQuery.

Vamos utilizar o código HTML abaixo, os estilos foram colocados direto no código apenas para fins didáticos, não façam isso.


<html>
  <head>
    <title>yLog Scroll Tutorial</title>
  </head>
  <body>
    <div id="content" style="width:120; height:100px; overflow-y:scroll;">
      <ul style="position: relative;">
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
        <li>item 6</li>
        <li>item 7</li>
        <li>item 8</li>
        <li>item 9</li>
        <li>item 10</li>
      </ul>
    </div>
  </body>
</html>

Ao abrir esse HTML no navegador aparecerá uma lista de itens com uma barra de rolagem. O que queremos é que ao rolar a barra até o fim novos itens apareçam. Para carregar conteúdo dessa forma usa-se AJAX, nada muito complicado, mas a maior dúvida é como saber se a barra chegou ao final.

Primeiro importe o JQuery, adicione a linha abaixo entre as tags <head></head>. É uma boa prática importar ele direto do Google.


<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>

Existe um evento chamado "scroll", nome mais óbvio impossível. Vamos usar ele para fazer algo quando a barra for rolada. Adicione esse código logo abaixo a linha que importa o JQuery.

<script>
  $(document).ready(function() {
    $("#content").scroll(function() { 
      //fazer algo aqui
    });
  });
</script>

Com os métodos scrollTop() e height() é possível saber o quanto foi rolado e a altura da div, mas essa não é a altura total, ela é a altura apenas do que está sendo exibido. Para saber o tamanho total da div é necessário usar a propriedade .scrollHeight. Com esses três valores é possível fazer o cálculo para saber se a rolagem chegou ao fim. O quanto foi rolado somado a altura de exibição da div será igual ao tamanho total da div quando a barra de rolagem chegar ao final. No código isso seria: $(this).scrollTop() + $(this).height() == $(this).get(0).scrollHeight.

Atualizando nosso script:

<script>
  $(document).ready(function() {
    $("#content").scroll(function() { 
      if ($(this).scrollTop() + $(this).height() == $(this).get(0).scrollHeight) {
        // a rolagem chegou ao fim, fazer algo aqui.
      }
    });
  });
</script>

Dentro do if você só precisa usar AJAX para pegar os dados do servidor. Ficaria algo mais ou menos assim:


<script>
  $(document).ready(function() {
    $("#content").scroll(function() { 
      if ($(this).scrollTop() + $(this).height() == $(this).get(0).scrollHeight) {
        $.ajax({
          type: "post",
          url: "/maisitems/",
          success: function(data) {
            //manipula os dados
            $("#content ul").append("<li>" + item + "</li>");
          },
          error: function() {
          }
        });
      }
    });
  });
</script>


O código completo do HTML + Javascript fica assim:


<html>
  <head>
    <title>yLog Scroll Tutorial</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>  
    <script>
      $(document).ready(function() {
        $("#content").scroll(function() { 
          if ($(this).scrollTop() + $(this).height() == $(this).get(0).scrollHeight) {
            console.log("fim");
            $("#content ul").append("<li>item x</li>");

            $.ajax({
              type: "post",
              url: "/maisitems/",
              success: function(data) {
                  //manipula os dados
                  $("#content ul").append("<li>" + item + "</li>");
              },
              error: function() {
              }
            });
          }
        });
      });
    </script>
  </head>
  <body>
    <div id="content" style="width:120; height:100px; overflow-y:scroll;">
      <ul style="position: relative;">
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
        <li>item 5</li>
        <li>item 6</li>
        <li>item 7</li>
        <li>item 8</li>
        <li>item 9</li>
        <li>item 10</li>
      </ul>
    </div>
  </body>
</html>

Espero que tenham gostado dessa dica. Se necessário gravem esse código final, ele pode ser útil.

3 comentários:

  1. Muito bom, Yuri :D

    Estou tentando aprender javascript, tava pensando em algum projeto interessante pra desenvolver, mas ainda não decidi. O máximo que fiz foi o http://qualeaoperadora.de. Aceito sugestões :)

    ResponderExcluir
  2. Olha as novidades do HTML5, tem muita coisa interessante, inclusive para javascript. Essa apresentação do Google deve te ajudar a se inspirar: http://slides.html5rocks.com

    Ah, achei muito legal o "Qual a operadora de", parabéns.

    ResponderExcluir
  3. cara, vlw.
    estava procurando isso a muito tempo.
    xD

    ResponderExcluir