@dataWave

Как реализовать бесконечный(почти) календарь?

clauderic.github.io/react-infinite-calendar/#/basi...
Необходимо реализовать подобный календарь со скроллом вверх и вниз.
Проблема в том, что необходимый диапазон лет в моем случае - 200. А в данном решении просто зарендерили 70, разом.
Как вы понимаете 200 лет грузить разом - слишком затратно для производительности, а частями грузить у меня не получилось, т.к после перерендера меняется высота блока и после вставки, например, предыдущего года, он показывает верхушку контента, сбрасывая скролл в начало блока.

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

Как можно совладать с прыгающим скроллом и незаметно для пользователя генерировать и вставлять данные?
Пишу на react hooks.
  • Вопрос задан
  • 387 просмотров
Пригласить эксперта
Ответы на вопрос 2
IonDen
@IonDen
JavaScript developer. IonDen.com
Довольно сомнительное решение с точки зрения дизайна интерфейса.
На 70 лет то тяжело управлять и скролить в нужное место, а уж на 200 лет - да в жизни не перемотаешь куда надо.

Но если все-таки очень нужно, то лучше вам сменить подход к проблеме. Смотрите:
1. Пользователь может неспешно проматывать вниз (можно загружать по мере прокрутки)
2. Пользователь может сразу ткнуть в конец или в середину (а вот тут проблема придется подгрузить все то, что пользователь проскочил).

Но проблему уже решили до нас создатели карт!
Будь то гугл.карты, яндекс.карты или что-то еще - там все грузится и рендерится совершенно по другому, в зависимости от координат, которые вы открыли.

Соответственно вашу задачу можно будет решить похожим образом.

1. Вы создаете огромный (но полностью пустой) слой. Шириной с ваш календарь, и высотой во много тысяч пикселей
2. Эту высоту вы вычислите исходя из кол-ва лет что у вас в конфиге.
3. Далее после того как юзер проскролил на какую-то точку - вы должны будете вычислить вьюпорт + scrollTop
4. На основании этих данных вы отрендерите только 2-3 года календаря которые совпадают с координатами на которые проскролил юзер и покажите их в этих координатах с помощью position-absolute
5. Примерно так.

+ Данный метод гораздо надежнее чем прокрутка подряд и черная магия с дорисовкой элементов и прыгающим скроллом
+ Данный метод позволит вам рендерить только те части календаря которые видит пользователь. То что вне вьюпорта - отрендерено не будет и соответственно не будет тормозить.
- Придется хорошенько посидеть, подумать, вспомнить матан)
Ответ написан
@Karpion
Ну, я бы сделал как-то иначе, примерно так:
Есть окно примерно на один месяц, т.е. на шесть недель (т.к. месяц на 31 день занимает четыре недели три дня, причём эти три дня м.б. в разных неделях). В нём показывают ровно то, что влезает. Склоллинг колёсиком мышки приводит к перемещению на одну неделю за клик колёсика. При этом никакого скролл-бара справа нет, там строго шесть недель.

А сбоку - возможность кликом выбрать месяц и год. Не выпадающий список, а всегда развёрнутый; месяцы должны влезть на экран, а годы - со скроллом. Впрочем, нужен ли скролл - должно определяться по факту того, влез ли список в экран.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
КРАФТТЕК Санкт-Петербург
от 60 000 до 80 000 ₽
summer Ярославль
от 100 000 до 140 000 ₽