Несколько схем для Touchmove для отключения прокрутки по умолчанию
предисловие
Поделитесь некоторыми проблемами и решениями, возникшими в реальном процессе разработки.Если в тексте есть что-то не так, вы можете указать и подбодрить друг друга. !
Адрес личного блога🍹🍰 fe-код
задний план
В связи с недавним спросом на мобильную бегущую строку событие touchmove используется для запуска анимации бегущей строки. Однако в реальных условиях было обнаружено, что можно легко запустить вертикальную прокрутку самой страницы при перемещении вращающейся лампы, как показано на следующем рисунке.
Примечание: используется здесь
overflow: autoСмоделируйте бегущую строку и выполните только тесты касания.

Можно видеть, что во время процесса скольжения, как только направление скольжения наклоняется к вертикальному направлению, запускается вертикальная прокрутка страницы.
строить планы
Passive event listeners
Поскольку это вертикальная прокрутка, запускаемая событием touchmove, легко думать о передачеe.preventDefault()Чтобы отключить поведение события по умолчанию, код легко изменить.
function Touch() {
const startTouchRef = useRef({x: 0, y: 0});
// 保存初始位置
function onTouchStart(e) {
startTouchRef.current = { x: e.touches[0].pageX, y: e.touches[0].pageY };
}
// 限制垂直方向上的滚动
function onTouchMove(e) {
const y = Math.abs(e.touches[0].pageY - startTouchRef.current.y);
const x = Math.abs(e.touches[0].pageX - startTouchRef.current.x);
// 简单判断滑动方向是倾向于 y 还是 x
// 禁止 x 方向的默认滚动,因为 x 方向的滚动会通过 Touchmove 或者 css 动画 实现
if (y < x) {
e.preventDefault();
}
}
return (
<div onTouchStart={onTouchStart}
onTouchMove={onTouchMove}>
// ...
</div>
)
}
В конце легко получить ошибку.
Это человеческий фактор, давайте проверимwoohoo.chrome status.com/features/50…этот URL.
Общая идея такова: addEventListener имеет пассивный параметр, который по умолчанию равен false, но в Chrome 56 touchstart и touchmove изменены на значения по умолчанию.passive: true. Таким образом, событие touchmove не будет блокировать прокрутку страницы. Потому чтоpassive: falseсостояние, независимо от того, нужно ли вызыватьe.preventDefault()Чтобы страница не прокручивалась, вам нужно дождаться выполнения функции touchmove, прежде чем страница ответит.
Проведите простой тест.
// 没有阻止页面滚动,仅仅是增加了事件处理的时间
function Touch() {
const ref = useRef(null);
function onTouchMove(e) {
console.time();
let index = 0;
for (let i = 0; i< 1000000000; i++) {
index++;
}
console.timeEnd();
}
useEffect(() => {
ref.current.addEventListener('touchmove', onTouchMove, { passive: false });
return () => {
ref.current.removeEventListener('touchmove', onTouchMove, { passive: false });
};
}, []);
return (
<div >
// ...
</div>
)
}
После каждого пролистывания ответ страницы явно зависает, потому что браузеру нужно дождаться завершения сенсорного перемещения, прежде чем он узнает, следует ли отключить прокрутку по умолчанию. Когда для пассивного параметра установлено значение true, браузер не будет рассматривать возможность отключения поведения по умолчанию и немедленно активирует поведение страницы.
Конечно, если вы действительно хотите предотвратить поведение по умолчанию, как в моем предыдущем требовании, вам нужно вручную установить для пассивного значения значение false, а затем использовать preventDefault в обычном режиме. Однако в любом случае нам необходимо оптимизировать исполняемый код, чтобы свести к минимуму время выполнения временного кода. В противном случае вы также увидите следующее предупреждение:
Что касается пассивного мониторинга событий, то на мобильной стороне больше оптимизации, а на стороне ПК, похоже, обрабатывается меньше. Я тестировал здесь только колесико мыши в Chrome 74 на ПК, хотя для него установлено значениеpassive: true, и предпочтительно не запускает прокрутку страницы. Однако в мобильном режиме это возможно. Кому интересно, может проверить на себе.
Поскольку пассивный режим поддерживается только в Chrome 56 и более поздних версиях, при его использовании вам может потребоваться выполнить тест на совместимость. код отMDN.
// 如果触发对 options 取值 passive 的情况,说明支持 passive 属性
var passiveSupported = false;
try {
var options = Object.defineProperty({}, "passive", {
get: function() {
passiveSupported = true;
}
});
window.addEventListener("test", null, options);
} catch(err) {}
someElement.addEventListener("mouseup", handleMouseUp, passiveSupported
? { passive: true } : false);
touch-action
Область, используемая для настройки того, как пользователи сенсорного экрана манипулируют элементами (например, встроенная в браузер функция масштабирования). —MDN
Это свойство css, проще говоря, его можно указать с помощью css.разрешатьДействие жеста, используемое пользователем.
- pan-x включает жесты горизонтального панорамирования одним пальцем
- pan-y включает вертикальное панорамирование одним пальцем
- нет отключить операцию
Для других атрибутов вы можете перейти на MDN, чтобы проверить это самостоятельно. В сочетании с нашими потребностями использование pan-y только для открытия вертикальных операций также может дать аналогичный эффект. Следует отметить, что настройка touch-action, а мы устанавливаемpassive: falseПовторный вызов preventDefault имеет тот же эффект и не оптимизирует эффект скольжения в разрешенном направлении операции.
Кроме того, это свойство также имеет проблемы с совместимостью, а эффект поддержки в Safari оставляет желать лучшего.Подробнее см.can i use.
overflow
Для запрета прокрутки элементов мы фактически добавляем к его родительскому элементуoverflow: hiddenтакже можно добиться желаемого эффекта. Для всей страницы нужно добавить overflow: hidden в html-тег. Однако, исходя из текущего сценария спроса, поскольку мы не хотим запускать вертикальную прокрутку только при горизонтальном скольжении, нам нужно определить, когда устанавливать свойства, а когда их удалять.
Здесь я не делал этот тест специально, просто чтобы дать представление.
группа обмена
Группа внешнего обмена QQ: 960807765, приветствуем все виды технического обмена, с нетерпением ждем вашего присоединения;
Группа WeChat: нуждающиеся учащиеся могут добавить меня в WeChat (q1324210213), и я добавлю вас в группу.
постскриптум
Если вы это видите, и эта статья вам полезна, надеюсь, вы сможете поддержать автора своими ручонками, спасибо 🍻. Если в тексте что-то не так, укажите на это и поделитесь. Хорошо, я снова потратил впустую время всех, спасибо за чтение, увидимся в следующий раз!
- Репозиторий статей 🍹🍰fe-код
- Система социального чата (vue + node + mongodb) — 💘🍦🙈Vchat
Заинтересованные студенты могут обратить внимание на мой публичный номерпередний двигатель, весело и познавательно.