Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: PullToRefresh на мобильном сафари нестабильно работает #5670

Closed
rflban opened this issue Aug 21, 2023 · 1 comment · Fixed by #5967

Comments

@rflban
Copy link
Contributor

rflban commented Aug 21, 2023

Описание

Проблема с компонентом PullToRefresh в мобильном сафари - через раз вместо него срабатывает нативный

Версия

5.7.1

В каких браузерах воспроизводится проблема?

Safari

Шаги воспроизведения

Потянуть экран вверх. Иногда срабатывает нативный pull-to-refresh, иногда - vkui, а иногда - оба

Ожидаемое поведение

Всегда должен срабатывать vkui

Скриншоты

image image image

Пример с воспроизведением

https://codesandbox.io/embed/sleepy-banach-j3fsm5?fontsize=14&hidenavigation=1&theme=dark

смотреть на реальном айфоне или на эмуляторе xcode

@mendrew mendrew added this to VKUI Aug 21, 2023
@mendrew mendrew moved this to 🗃 Backlog in VKUI Aug 21, 2023
@inomdzhon inomdzhon added this to the v5.8.1 milestone Aug 25, 2023
@inomdzhon inomdzhon modified the milestones: v5.8.1, v5.8.2 Sep 12, 2023
@mendrew mendrew modified the milestones: v5.8.2, v5.9.0 Sep 25, 2023
@BlackySoul BlackySoul modified the milestones: v5.9.0, v5.10.0 Oct 2, 2023
@mendrew mendrew moved this from 🗃 Backlog to 🔧 In progress in VKUI Oct 11, 2023
@mendrew mendrew self-assigned this Oct 11, 2023
@mendrew mendrew moved this from 🔧 In progress to 👀 In Review in VKUI Oct 13, 2023
@mendrew mendrew modified the milestones: v5.10.0, v5.9.3 Oct 13, 2023
@github-project-automation github-project-automation bot moved this from 👀 In Review to ✅ Done in VKUI Oct 16, 2023
@vkcom-publisher
Copy link
Contributor

v5.9.3 🎉

mendrew added a commit that referenced this issue Oct 23, 2023
#6004)

- close #2806 
- related #5670 и #5967

* Описание
Ещё одна попытка победить нативный pull-to-refresh который периодически появляется при закрытии модалки или в PullToRefresh компоненте.

В целом событие `touchmove` на window уже игнорируется, но этого недостаточно, потому что для pull-to-refresh в мобильном Safari хватит и одного обработанного браузером`touchstart`. 

Используется css свойство [`overscroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior) на `html` элементе.

Перепробывал кучу других вариантов с `touchstart/touchmove` событиями, но единственный действенный это превентить `touchstart`. Но тогда перестаёт работать скролл внутри PullToRefresh, а через JS имитировать скролл браузера неблагодарная задача.

* Изменения
добавил глобальный класс, которые в последствии будут вешаться на `html` элемент при открытии модалки или при взаимодействии с PullToRefresh.
Сейчас уже работает наверняка для `PullToRefresh` компонента и покрывает баг в модалках если закрывать окно потянув из `ModalPageHeader`.

Используем классы, а не напрямую меняем style, чтобы не думать и не сохранять предыдущие значения `overscroll-behavior`, это также позволяет избавиться от чтения/записи стилей, чтобы не заставлять браузер готовить и пересчитывать для нас CSSOM в момент чтения/записи style.

** ModalPage
- устанавливаем `overscroll-behavior-y: none` когда модалка открыта

*** PullToRefresh
- класс вешается на `html` на событии `touchstart` и убирается в обработчике собитий `touchend/touchcancel`.

* Особенности PullToRefresh.
Так как убирается bounce-эффект, то страница становится менее отзывчивая (без эффекта) если это единственный компонент на странице и пользователь доскролил до конца страницы.
Но зато можно начать наш PullToRefresh даже если страница уже была чуть проскроллена вниз, а пользователь начал тянуть. Раньше можно было вызвать наш PullToRefresh только если страница имеет `scrollTop = 0` в момент начала жеста.

Есть вариант добиться `bounce` эффекта когда пользователь доскроли до конца страницы.
Например, добавить к уже имеющейся логику в `touchmove` и смотреть в какую сторону в пределах `PullToRefresh` пользователь скроллит, и если это скролл вниз (пальцем снизу вверх), то убирать класс, если снова скролл вверх, то добавлять класс. 
Но это так себе решение, потому что мы всегда в `touchstart` выставляем класс, и если пользователь сразу скроллит вниз, то получится, что класс добавиться и тут же убереться. Хотя, не сильно хуже чем сейчас, конечно, потому что мы сейчас и так всегда класс добавляем а на touchend/touchcancel убираем.
И ещё момент появится, что если пользователь уже доскроллил до конца страницы и попробует поскролить вниз ещё раз, то bounce-эффекта не будет, ведь на touchmove мы не поймём в какую сторону пользователь скролит. Хотя тут можно поиграться. И посмотреть scrollTop значение. 🤔 
Вопрос только стоит ли?
vkcom-publisher pushed a commit that referenced this issue Oct 23, 2023
#6004)

- close #2806
- related #5670 и #5967

* Описание
Ещё одна попытка победить нативный pull-to-refresh который периодически появляется при закрытии модалки или в PullToRefresh компоненте.

В целом событие `touchmove` на window уже игнорируется, но этого недостаточно, потому что для pull-to-refresh в мобильном Safari хватит и одного обработанного браузером`touchstart`.

Используется css свойство [`overscroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior) на `html` элементе.

Перепробывал кучу других вариантов с `touchstart/touchmove` событиями, но единственный действенный это превентить `touchstart`. Но тогда перестаёт работать скролл внутри PullToRefresh, а через JS имитировать скролл браузера неблагодарная задача.

* Изменения
добавил глобальный класс, которые в последствии будут вешаться на `html` элемент при открытии модалки или при взаимодействии с PullToRefresh.
Сейчас уже работает наверняка для `PullToRefresh` компонента и покрывает баг в модалках если закрывать окно потянув из `ModalPageHeader`.

Используем классы, а не напрямую меняем style, чтобы не думать и не сохранять предыдущие значения `overscroll-behavior`, это также позволяет избавиться от чтения/записи стилей, чтобы не заставлять браузер готовить и пересчитывать для нас CSSOM в момент чтения/записи style.

** ModalPage
- устанавливаем `overscroll-behavior-y: none` когда модалка открыта

*** PullToRefresh
- класс вешается на `html` на событии `touchstart` и убирается в обработчике собитий `touchend/touchcancel`.

* Особенности PullToRefresh.
Так как убирается bounce-эффект, то страница становится менее отзывчивая (без эффекта) если это единственный компонент на странице и пользователь доскролил до конца страницы.
Но зато можно начать наш PullToRefresh даже если страница уже была чуть проскроллена вниз, а пользователь начал тянуть. Раньше можно было вызвать наш PullToRefresh только если страница имеет `scrollTop = 0` в момент начала жеста.

Есть вариант добиться `bounce` эффекта когда пользователь доскроли до конца страницы.
Например, добавить к уже имеющейся логику в `touchmove` и смотреть в какую сторону в пределах `PullToRefresh` пользователь скроллит, и если это скролл вниз (пальцем снизу вверх), то убирать класс, если снова скролл вверх, то добавлять класс.
Но это так себе решение, потому что мы всегда в `touchstart` выставляем класс, и если пользователь сразу скроллит вниз, то получится, что класс добавиться и тут же убереться. Хотя, не сильно хуже чем сейчас, конечно, потому что мы сейчас и так всегда класс добавляем а на touchend/touchcancel убираем.
И ещё момент появится, что если пользователь уже доскроллил до конца страницы и попробует поскролить вниз ещё раз, то bounce-эффекта не будет, ведь на touchmove мы не поймём в какую сторону пользователь скролит. Хотя тут можно поиграться. И посмотреть scrollTop значение. 🤔
Вопрос только стоит ли?
vkcom-publisher pushed a commit that referenced this issue Oct 23, 2023
#6004)

- close #2806
- related #5670 и #5967

* Описание
Ещё одна попытка победить нативный pull-to-refresh который периодически появляется при закрытии модалки или в PullToRefresh компоненте.

В целом событие `touchmove` на window уже игнорируется, но этого недостаточно, потому что для pull-to-refresh в мобильном Safari хватит и одного обработанного браузером`touchstart`.

Используется css свойство [`overscroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior) на `html` элементе.

Перепробывал кучу других вариантов с `touchstart/touchmove` событиями, но единственный действенный это превентить `touchstart`. Но тогда перестаёт работать скролл внутри PullToRefresh, а через JS имитировать скролл браузера неблагодарная задача.

* Изменения
добавил глобальный класс, которые в последствии будут вешаться на `html` элемент при открытии модалки или при взаимодействии с PullToRefresh.
Сейчас уже работает наверняка для `PullToRefresh` компонента и покрывает баг в модалках если закрывать окно потянув из `ModalPageHeader`.

Используем классы, а не напрямую меняем style, чтобы не думать и не сохранять предыдущие значения `overscroll-behavior`, это также позволяет избавиться от чтения/записи стилей, чтобы не заставлять браузер готовить и пересчитывать для нас CSSOM в момент чтения/записи style.

** ModalPage
- устанавливаем `overscroll-behavior-y: none` когда модалка открыта

*** PullToRefresh
- класс вешается на `html` на событии `touchstart` и убирается в обработчике собитий `touchend/touchcancel`.

* Особенности PullToRefresh.
Так как убирается bounce-эффект, то страница становится менее отзывчивая (без эффекта) если это единственный компонент на странице и пользователь доскролил до конца страницы.
Но зато можно начать наш PullToRefresh даже если страница уже была чуть проскроллена вниз, а пользователь начал тянуть. Раньше можно было вызвать наш PullToRefresh только если страница имеет `scrollTop = 0` в момент начала жеста.

Есть вариант добиться `bounce` эффекта когда пользователь доскроли до конца страницы.
Например, добавить к уже имеющейся логику в `touchmove` и смотреть в какую сторону в пределах `PullToRefresh` пользователь скроллит, и если это скролл вниз (пальцем снизу вверх), то убирать класс, если снова скролл вверх, то добавлять класс.
Но это так себе решение, потому что мы всегда в `touchstart` выставляем класс, и если пользователь сразу скроллит вниз, то получится, что класс добавиться и тут же убереться. Хотя, не сильно хуже чем сейчас, конечно, потому что мы сейчас и так всегда класс добавляем а на touchend/touchcancel убираем.
И ещё момент появится, что если пользователь уже доскроллил до конца страницы и попробует поскролить вниз ещё раз, то bounce-эффекта не будет, ведь на touchmove мы не поймём в какую сторону пользователь скролит. Хотя тут можно поиграться. И посмотреть scrollTop значение. 🤔
Вопрос только стоит ли?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants