Seções iMasters
JavaScript + JQuery

Como carregar conteúdo sob demanda usando jQuery

Sites como o Facebook e o 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, à medida que o usuário vai descendo a barra de rolagem, o site se encarrega de pegar mais dados no servidor para exibir.

O efeito é não é complicado de fazer, além de ser 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 importá-lo 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 usá-lo para fazer algo quando a barra for rolada. Adicione esse código logo abaixo da 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 à 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.

Mensagem do anunciante:

Curso ao vivo de WordPress: Aprenda a gerenciar conteúdo no CMS mais popular do mundo com o Apiki WP Cursos. Vagas limitadas, matricule-se agora. Cursos Apiki

Comente também

29 Comentários

Olha você no iMasters!

    cleomar

    em pessoal me respondem o quanto antes pfv, olha fis diferente o sistema, mais assim eu queria fazer assim, quando ele adicionar mais um item, ele tenha uma class tipo

    pra mim fazer tipo quando clicar alertar entendeu, me add no msn cleomar-_@hotmail.com ou no face cleomar.olykan obrigado

Eu nem sabia que existia esse site…

    João Lucas Silva

    Muito juvenil … Imasters existe há mais de uma década.

que legal, obrigado por esse artigo, me foi muito útil.

Bom dia. Artigo muito útil.
Apenas uma dica que muitos desenvolvedores JS ignoram. No trecho :

if ($(this).scrollTop() + $(this).height() == $(this).get(0).scrollHeight) {

Uma boa prática seria criar uma variável local que receba o “$(this)”. Mais ou menos assim:

var elem = $(this);
if (elem.scrollTop() + elem.height() == elem[0].scrollHeight) {

A função “$” ou “jQuery” faz muitas verificações e é uma boa prática usá-la somente uma vez no caso acima.

    Yuri Malheiros

    Ótima dica, Vitor. Obrigado por ajudar a melhorar o código :)

    João Lucas Silva

    Normalmente usam:
    $this = $(this);

    De movo a evitar que você escreve mais rápido em vez de ficar escrevendo parênteses e também por questões de desempenho.

Thomas Lopes

Olá!

Dica muito legal! Mas me parece faltar agora nesse trecho:

success: function(data) {
//manipula os dados
$(“#content ul”).append(“” + item + ““);
},

Parece que falta um each que manipule o data e itere sobre os item’s.

    Yuri Malheiros

    Sim, você está certo. No lugar do comentário “//manipula os dados” é necessário adicionar código para manipular o data, mas como ela pode variar de acordo com sua aplicação eu resolvi deixar apenas o comentário alertando o que deve ser feito nessa parte.

Aderlan Rodrigues

Parabéns Yuri, excelente artigo.
Parabéns também para o Vitor, excelente dica!

Já tive algumas ideias para usar esse código, vou colocar a mão na massa!

Valeu!

    Yuri Malheiros

    Ótimo ouvir isso, Aderlan :) Espero que funcione direitinho para o que você precisa.

    João Lucas Silva

    A intenção é boa, mas além de ser um artigo muito juvenil, possui alguns erros e coisas sem nexos, mas para bom entendedor, meio palavra basta.

Como seria este each ali?
Alguém tem um exmplo de conteúdo a ser man

André

Assim ele não vai trazer os mesmos registros sempre?Como foi feito o controle de quais registros vão ser selecionados para a próxima visualização?Tipo paginação…

Franklin

Complementando o que o Vitor disse, sempre que usar um elemento mais de uma vez, é sempre bom cachea-lo, não necessitando que o jquery percorra o DOM novamente até encontrar o elemento.

Pedro

Como seria este each ?

Anderson Coimbra

Olá Yuri…td certo?

Esse “maisitems” no url, seria o que? é uma pasta de q?
type: “post”,
url: “/maisitems/”,

Rafael Bilar

Muito Legal. Parabéns.

André Rocha

Corrija o código, na parte de style da div.
Deve colocar o width e o height como pixels, senao não funciona o scroll.

Obrigado.

Abraço

paulo

malta eu gostaria de saber com fazer o slide de imagem a quem duma pasta e o seu caminho e descrições da bd

wallace

Cara vc salvou a minha vida

Hugo Santos

Daria pra usar esse código ao invés de ser com rolagem, carregar um grupo de imagens da página apenas se a pessoa clicar em uma ancora?

cleomar

em pessoal me respondem o quanto antes pfv, olha fis diferente o sistema, mais assim eu queria fazer assim, quando ele adicionar mais um item, ele tenha uma class tipo
pra mim fazer tipo quando clicar alertar entendeu, me add no msn cleomar-_@hotmail.com ou no face cleomar.olykan obrigado

Rodrigo

show de bola!!! valew pelo artigo

Alexjunior Nogueira Alves

Muito bom Yuri parabéns pelo post, já estou utilizando este código na minha loja virtual. Obrigado.

Jhonatan Lopes

Olá! código muitointeressante! Meu problema é que consigo carregar quanquer conteudo, mas APENAS deixando a barra de rolagem que veio no código. Tentei colocar um texto grande, e tirei os atributos da div que estava com a barra de rolagem , mas o conteudo não é carregado… Alguém poderia me ajudar?

Douglas

Opa, O Jhonatan é só trocar o IF por este aqui ó

if ($(window).scrollTop() + $(window).height() >= $(document).height()) {

Espero que tenha ajudado =]

Qual a sua opinião?