Como rolar para um item específico usando jQuery?

252

Eu tenho uma mesa grande com barra de rolagem vertical. Gostaria de rolar para uma linha específica nesta tabela usando jQuery / Javascript.

Existem métodos internos para fazer isso?

Aqui está um pequeno exemplo para brincar.

div {
    width: 100px;
    height: 70px;
    border: 1px solid blue;
    overflow: auto;
}
<div>
    <table id="my_table">
        <tr id='row_1'><td>1</td></tr>
        <tr id='row_2'><td>2</td></tr>
        <tr id='row_3'><td>3</td></tr>
        <tr id='row_4'><td>4</td></tr>
        <tr id='row_5'><td>5</td></tr>
        <tr id='row_6'><td>6</td></tr>
        <tr id='row_7'><td>7</td></tr>
        <tr id='row_8'><td>8</td></tr>
        <tr id='row_9'><td>9</td></tr>
    </table>
</div>

Misha Moroshko
fonte

Respostas:

563

Simplesmente morto. Não são necessários plugins .

var $container = $('div'),
    $scrollTo = $('#row_8');

$container.scrollTop(
    $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
);

// Or you can animate the scrolling:
$container.animate({
    scrollTop: $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
});​

Aqui está um exemplo de trabalho .

Documentação parascrollTop .

James
fonte
4
Se o recipiente tem uma barra de rolagem, você precisará conta para o scrollTop: scrollTo.offset () superior - container.offset () superior + container.scrollTop ()..
claviska
1
Você pode rolar a janela inteira com $ (document) .scrollTop (value) - o código jquery subjacente resolve os problemas do navegador para você.
31512 Chris Moschini
7
Se você deseja scrollTocentralizar, e não no topo:scrollTo.offset().top - container.offset().top + container.scrollTop() - (container.height()/2)
Mahn
7
element.scrollIntoView()- isso é tudo o que é necessário. A animação é padronizada. Veja developer.mozilla.org/pt-BR/docs/Web/API/Element/scrollIntoView
WickyNilliams
7
Observe que há um caractere "invisível" no final do bloco de código. O caractere é considerado inválido no Edge, chrome. - um copy-paster
Attacktive
114

Sei que isso não responde à rolagem em um contêiner, mas as pessoas acham útil:

$('html,body').animate({scrollTop: some_element.offset().top});

Selecionamos html e body porque o scroller de documentos pode estar em um dos dois e é difícil determinar qual deles. Para navegadores modernos, você pode se safar $(document.body).

Ou, para ir para o topo da página:

$('html,body').animate({scrollTop: 0});

Ou sem animação:

$(window).scrollTop(some_element.offset().top);

OU...

window.scrollTo(0, some_element.offset().top); // native equivalent (x, y)
Dominic
fonte
ola @infensus você pode me dar um exemplo de trabalho dessa causa a minha não está funcionando? eu usei var section2 = $ ('# section-2'); $ ('html, body'). animate ({scrollTop: section2.offset (). top});
dll_onFire
Parece bom - você tem certeza de que a seção 2 existe? faça console.log (section2.length); e verifique se não é 0. Irá dar um exemplo daqui a pouco.
Dominic
Por que $('html,body')? Ele precisa apenas em contêiner específico. Resposta aceita é melhor para mim. Eu tenho um caso semelhante ao da pergunta e sua resposta não funcionou para mim.
Petrol #
2
@ Petroff estranhamente quando escrevi isso, não percebi que o elemento estava em um contêiner de rolagem. Vou deixar a minha resposta como é, porque embora as pessoas vêm aqui a partir de uma pesquisa do Google para rolar o corpo devido ao título da pergunta
Dominic
30

Eu concordo com Kevin e outros, o uso de um plugin para isso é inútil.

window.scrollTo(0, $("#element").offset().top);
Fredrik Stolpe
fonte
Para algo que deveria ser tão simples, passei anos em outras soluções on-line, mas esse liner simples faz exatamente o que eu preciso.
Laurence Cope
3
Note-se, desta forma, funciona para toda a janela. Se você deseja rolar o conteúdo que está excedendo: role, isso não funcionará.
Jeremy
12

Eu consegui fazer isso sozinho. Não há necessidade de plugins. Confira minha essência :

// Replace #fromA with your button/control and #toB with the target to which     
// You wanna scroll to. 
//
$("#fromA").click(function() {
    $("html, body").animate({ scrollTop: $("#toB").offset().top }, 1500);
});
lorddarq
fonte
Sua essência de uma linha, completa com animação, era exatamente o que eu precisava. Obrigado!
Scott Smith
No need for any plugins?? Mas você usa jQuery! É uma biblioteca enorme, nem mesmo um plugin.
Verde
1
Você não precisa adicionar uma referência além da referência da biblioteca jquery. Além disso, o jquery é um tipo de padrão da indústria. Por que você não o usaria? Provavelmente é possível sem o jquery, mas ainda seria necessário que alguém escrevesse muito código apenas para a parte de análise. Parece contraproducente. E parecia contraproducente escrever um plugin completo apenas para rolar para uma div medíocre.
Lorddarq
4

Você pode usar o scrollIntoView()método em javascript. apenas dêid.scrollIntoView();

Por exemplo

row_5.scrollIntoView();
Tamilarasi
fonte
Como animá-lo?
Verde
Não há necessidade de animar. Quando você usa scrollIntoView (), o controle será rolado automaticamente para torná-lo exibido na exibição.
Tamilarasi
4

Você pode usar o plugin do plugin jQuery scrollTo :

$('div').scrollTo('#row_8');
nickf
fonte
1
o link não está mais disponível. você poderia atualizá-lo?
Lucky
2

Role o elemento para o centro do contêiner

Trazer o elemento para o centro do contêiner.

DEMO no CODEPEN

JS

function scrollToCenter() {
  var container = $('.container'),
    scrollTo = $('.5');

  container.animate({
    //scrolls to center
    scrollTop: scrollTo.offset().top - container.offset().top + scrollTo.scrollTop() - container.height() / 2
  });
}

HTML

<div class="container">
   <div class="1">
    1
  </div>
  <div class="2">
    2
  </div>
  <div class="3">
    3
  </div>
  <div class="4">
    4
  </div>
  <div class="5">
    5
  </div>
  <div class="6">
    6
  </div>
  <div class="7">
    7
  </div>
  <div class="8">
    8
  </div>
  <div class="9">
    9
  </div>
  <div class="10">
    10
  </div>


</div>
<br>
<br>
<button id="scroll" onclick="scrollToCenter()">
  Scroll
</button>

css

.container {
  height: 60px;
  overflow-y: scroll;
  width 60px;
  background-color: white;
}

Não é exato para o centro, mas você não o reconhecerá em elementos maiores e maiores.

basti500
fonte
2

Você pode rolar por jQuery e JavaScript. Apenas é necessário dois elementos jQuery e este código JavaScript:

$(function() {
  // Generic selector to be used anywhere
  $(".js-scroll-to-id").click(function(e) {

    // Get the href dynamically
    var destination = $(this).attr('href');

    // Prevent href=“#” link from changing the URL hash (optional)
    e.preventDefault();

    // Animate scroll to destination
    $('html, body').animate({
      scrollTop: $(destination).offset().top
    }, 1500);
  });
});

MD Ashik
fonte
1

Fiz uma combinação do que os outros postaram. É simples e suave

 $('#myButton').click(function(){
        $('html, body').animate({
            scrollTop: $('#scroll-to-this-element').position().top },
            1000
        );
    });
Nlinscott
fonte
@ AnriëtteMyburgh não tem certeza se position () está funcionando em todos os navegadores. Você já tentou isso em outras pessoas para ver se funciona? Ou posso ver o código que você está usando e ver se há algo errado?
Nlinscott
1

Não sei por que ninguém diz o óbvio, pois há uma scrollTofunção javascript embutida:

scrollTo( $('#element').position().top );

Referência .

Kevin
fonte
6
scrollTo requer dois argumentos, você escreveu apenas um.
NuclearPeon
2
... e é chamado no objeto da janela.
hashchange
1

Ao contrário do que a maioria das pessoas aqui estão sugerindo, eu recomendo que você faça usar um plugin se você quiser animar o movimento. Apenas animar o scrollTop não é suficiente para uma experiência suave do usuário. Veja minha resposta aqui para o raciocínio.

Eu tentei vários plugins ao longo dos anos, mas acabei escrevendo um. Você pode querer dar uma olhada : jQuery.scrollable . Usando isso, a ação de rolagem se torna

$container.scrollTo( targetPosition );

Mas isso não é tudo. Também precisamos fixar a posição alvo. O cálculo que você vê em outras respostas,

$target.offset().top - $container.offset().top + $container.scrollTop()

funciona principalmente, mas não está totalmente correto. Ele não manipula a borda do contêiner de rolagem corretamente. O elemento de destino é rolado para cima demais, pelo tamanho da borda. Aqui está uma demonstração.

Portanto, uma maneira melhor de calcular a posição alvo é

var target = $target[0], 
    container = $container[0];

targetPosition = $container.scrollTop() + target.getBoundingClientRect().top - container.getBoundingClientRect().top - container.clientTop;

Mais uma vez, dê uma olhada na demonstração para vê-la em ação.

Para uma função que retorna a posição de destino e funciona para contêineres de rolagem de janela e não de janela, fique à vontade para usar essa essência . Os comentários aqui explicam como a posição é calculada.

No começo, eu disse que seria melhor usar um plugin para rolagem animada . Você não precisa de um plug-in, no entanto, se quiser pular para o destino sem uma transição. Veja a resposta de @James para isso, mas certifique-se de calcular a posição de destino corretamente se houver uma borda ao redor do contêiner.

hashchange
fonte
0

Pelo que vale, é assim que eu consegui obter esse comportamento para um elemento geral que pode estar dentro de um DIV com rolagem (sem conhecer o contêiner)

Ele cria uma entrada falsa da altura do elemento de destino e, em seguida, coloca um foco nele, e o navegador cuidará do resto, não importa o quão profundo você esteja na hierarquia de rolagem. Funciona como um encanto.

var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');

$scrollTo.prepend(inputElem);
inputElem.css({
  position: 'absolute',
  width: '1px',
  height: $scrollTo.height()
});
inputElem.focus();
inputElem.remove();
martinh_kentico
fonte
0

Eu fiz essa combinação. é trabalho para mim. mas enfrentando um problema, se clicar em mover, o tamanho da div é muito grande para que o cenário não role para baixo até essa div específica.

 var scrollDownTo =$("#show_question_" + nQueId).position().top;
        console.log(scrollDownTo);
        $('#slider_light_box_container').animate({
            scrollTop: scrollDownTo
            }, 1000, function(){
        });

        }
scode2704
fonte