Как можно синхронизировать полосы прокрутки между двумя элементами без рекурсивного вызова каждого события?

Обычно вы ожидаете следующий код:

$div1.scroll(function() {
    $div2.scrollTop($div1.scrollTop());
});
$div2.scroll(function(){
    $div1.scrollTop($div2.scrollTop());
});

Но в этом случае, если вы прокрутите $ div1 1px, он также прокрутит $ div2 1px, что вызовет запуск события прокрутки $ div2 и повторное применение позиции прокрутки к $ div1. Хотя это может показаться не проблемой, но когда этот код применяется к странице и вы, естественно, прокручиваете с помощью мыши, он прокручивается с шагом 1 пиксель, потому что обработчики вызывают друг друга и не позволяют прокручивать.

Итак, как бы вы решили эту проблему?

Пример: https://jsfiddle.net/axtn/a91fsar3/2.

0
Alex 23 Июн 2017 в 08:49

1 ответ

Лучший ответ

Нашел хорошее решение. Debouncing делает свое дело.

Вы можете использовать комбинацию таймеров и логических значений, чтобы убедиться, что элемент прокручивается пользователем. Таким образом, когда событие прокрутки запускается быстро и последовательно (например, когда пользователь прокручивает вниз), оно не позволяет обработчикам рекурсивно вызывать друг друга. Следующий код делает свое дело:

var userScroll1 = true;
var userScroll2 = true;
var timer;

$div1.scroll(function() {
  if(userScroll2) {
    userScroll1 = false;
    clearTimeout(timer);
    $div2.scrollTop($div1.scrollTop());
    timer = setTimeout(function() {
       userScroll1 = true;
     }, 100);
  }
});
$div2.scroll(function(){
  if(userScroll1) {
    userScroll2 = false;
    clearTimeout(timer);
    $div1.scrollTop($div2.scrollTop());
    timer = setTimeout(function() {
       userScroll2 = true;
     }, 100);
  }
});

Проверьте правильно работающий jsbin: https://jsfiddle.net/axtn/a91fsar3

0
Alex 18 Окт 2017 в 00:39