Кривой скроллинг к элементу

161
03 марта 2017, 01:13

Доброго времени суток.

Задача: сделать аккордеон с функционалом, как на данном сайте - https://smylhub.com/. Почему при нажатиях на <a> скролл происходит не в правильное место (оно всегда разное)? Пытался использовать плагины - результат тот же.

HTML:

<pre>
  <ul class="accordeon_list">
    <li class="accordeon_item active" id="ac_itm_1">
      <a href="#" class="accordeon_trigger" id="ac_btn_1">click1</a>
      <span class="accordeon_inner">content</span>
    </li>
    <li class="accordeon_item" id="ac_itm_2">
      <a href="#" class="accordeon_trigger" id="ac_btn_2">click2</a>
      <span class="accordeon_inner">content</span>
    </li>
    <li class="accordeon_item" id="ac_itm_3">
      <a href="#" class="accordeon_trigger" id="ac_btn_3">click2</a>
      <span class="accordeon_inner">content</span>
    </li>
  </ul>
</pre>

JS:

$(".accordeon_trigger").click(function (){
  $('html, body').animate({
    scrollTop: $(this).closest(".accordeon_item").offset().top
  }, 2000);
});
Answer 1

Для начала запретите переход по якорю, добавив return false в конец обработчика события:

$(".accordeon_trigger").click(function (){
  ...
  return false;
});

Второе, вы написали не весь код, и я могу только догадываться. Как я понимаю, вы пытаетесь сразу настроить скролл на нужную позицию:

scrollTop: $(this).closest(".accordeon_item").offset().top

Перед этим вы назначили какую-то анимацию с блоками, какой-то блок скрывается, какой-то появляется, и почему-то решили, что offset() вернет вам не текущие координаты, а предскажет какие-то координаты из будущего.

Но дело в том, что фактически никаких изменений еще не произошло, и где будет offset().top после того как анимация блоков завершится не известно.

Решение

1) Вам нужно либо подождать, пока изменения придут в силу:

$(".accordeon_trigger").click(function (){
  setTimeout(function(){
      $('html, body').animate({
          scrollTop: $(this).closest(".accordeon_item").offset().top
      }, 2000);
  }), 1000) //1000 - длительность анимации с блоками
});

(setTimeout, не delay!)

2) Либо вычесть высоту скрываемого блока и добавить высоту появляемого блока

READ ALSO
Зависимость модулей

Зависимость модулей

Есть три куска кода:

240
Почему не получается запустить hot module replacement (React,Webpack)?

Почему не получается запустить hot module replacement (React,Webpack)?

Не получается запустить hmrПерехожу по ссылке http://localhost:3000/webpack-dev-server/bundle

271
Сжатие в javascript разжатие в django/python

Сжатие в javascript разжатие в django/python

Необходимо передать большую строку с клиента на серверХочу чтобы она сжималась на клиенте с помощью javascript и разжималась на сервере с помощью...

297