Como rolar a janela usando a função JQuery $ .scrollTo ()

98

Estou tentando rolar 100 pixels para baixo toda vez que o usuário chega perto do topo do documento.

Tenho a função em execução quando o usuário chega perto do início do documento, mas a função .scrollTo não está funcionando.

Coloquei um alerta antes e depois para verificar se realmente era a linha ou não que o estava interrompendo e apenas o primeiro alerta dispara, aqui está o código:

alert("starting");
$.scrollTo({ top: '+=100px', left: '+=0px' }, 800);
alert("finished");

Eu sei que tenho a página jquery vinculada corretamente porque estou usando muitas outras funções jquery e todas elas funcionam bem. Também tentei remover o 'px' de cima e não parece fazer diferença.


fonte
3
O próprio Jquery pode estar funcionando bem, mas você tem certeza de que o plug-in scrollTo está vinculado corretamente? Altere um desses alertas para alert ($. ScrollTo);
Andrew

Respostas:

97

Se não está funcionando, por que você não tenta usar o método scrollTop do jQuery?

$("#id").scrollTop($("#id").scrollTop() + 100);

Se você deseja rolar suavemente, pode usar a função javascript setTimeout / setInterval básica para fazê-la rolar em incrementos de 1px em um determinado período de tempo.

Fermín
fonte
8
Observe se você deseja rolar a página inteira e não um elemento individual, use $ ('html, body') exatamente como Tim apontou aqui. Apenas $ ('body') não funcionará em todos os navegadores.
i--
321
$('html, body').animate({scrollTop: $("#page").offset().top}, 2000);
Mihai
fonte
19
Muitas vezes me pergunto por que as pessoas usam 'html, body' para scrollTop em vez de apenas 'html'. Alguma opinião sobre isso?
Scott Greenfield
+1 funcionou para mim;) Também estou interessado em saber por que, em html, bodyvez de apenas html?
Kato
9
@ScottGreenfield, @Kato: não tenho certeza do porquê, mas este comentário diz não incluir bodyquebras isso no Chrome 4: stackoverflow.com/questions/1890995/…
Yuji 'Tomita' Tomita
scrollTop: 0também está funcionando bem. Mas a duração diminui. Funciona bem se definido para 1000 na velocidade
shashwat
Esta é uma boa solução até que você queira adicionar um método completo - ele será executado duas vezes. A solução da @complistic é mais elegante e vai evitar isso.
plankguy de
41

jQuery agora suporta scrollTop como uma variável de animação.

$("#id").animate({"scrollTop": $("#id").scrollTop() + 100});

Você não precisa mais setTimeout / setInterval para rolar suavemente.

Todd
fonte
Tenho alguns erros de sintaxe - falta o seu {. Caso contrário, este é um bom ponto.
Joshua
1
Deveria ser em $("#id").offset().topvez disso?
codeulike
15

Para contornar o problema htmlvs body, resolvi isso não animando o css diretamente, mas sim chamando window.scrollTo();cada etapa:

$({myScrollTop:window.pageYOffset}).animate({myScrollTop:300}, {
  duration: 600,
  easing: 'swing',
  step: function(val) {
    window.scrollTo(0, val);
  }
});

Isso funciona bem sem nenhuma dificuldade de atualização, pois está usando JavaScript para vários navegadores.

Dê uma olhada em http://james.padolsey.com/javascript/fun-with-jquerys-animate/ para mais informações sobre o que você pode fazer com a função animar do jQuery.

complacente
fonte
1
Isto é brilhante. Eu só mudei window.pageYOffsetpara $(window).scrollTop()e window.scrollTo(0, val)para, $(window).scrollTop(val)então não preciso me preocupar com a compatibilidade do navegador.
leftclickben
1
Nunca pensei em passar um objeto para o método animado do jQuery assim. Muitos usos possíveis. Essa solução é ótima, obrigado.
Synexis
Sim, a técnica é uma contribuição significativa. Anteriormente, contornava problemas de navegador usando "window.scrollTo ()" diretamente, mas isso não permite um retorno de chamada "completo", nem uma promessa. Obrigado @complistic por esta solução. Além disso, meus agradecimentos a @leftclickben; Implementei sua variação usando ".scrollTop ()". Além disso, o artigo "james.padolsey", por link, é uma leitura concisa e muito interessante.
IAM_AL_X
Eu acho que "window.scrollTo ()" deve ser compatível com todos os navegadores modernos.
IAM_AL_X
7

Parece que você entendeu a sintaxe um pouco errada ... Suponho, com base no seu código, que você está tentando rolar para baixo 100px em 800 ms, se sim, isso funciona (usando scrollTo 1.4.1):

$.scrollTo('+=100px', 800, { axis:'y' });
Alconja
fonte
6

Na verdade, algo como

function scrollTo(prop){
    $('html,body').animate({scrollTop: $("#"+prop).offset().top +
 parseInt($("#"+prop).css('padding-top'),10) },'slow');
}

vai funcionar bem e apoiar o preenchimento. Você também pode suportar margens facilmente - para conclusão, veja abaixo

function scrollTo(prop){
    $('html,body').animate({scrollTop: $("#"+prop).offset().top 
+ parseInt($("#"+prop).css('padding-top'),10) 
+ parseInt($("#"+prop).css('margin-top'),10) +},'slow');
}
Tim
fonte