我已经在我的网站中实现了自定义触摸行为,并且使用触摸操作来防止浏览器处理用户手势。
问题是,当用户在带有 的元素上上下滑动时,Safari 将折叠并展开其底部的地址栏touch-action: none。内容不会滚动,这是预期的行为,但地址栏会更改其状态,但事实并非如此。这还会调整屏幕大小,导致布局变化和resize事件侦听器触发,并破坏用户体验。
Chrome 与 Safari 一样,底部也有一个 UI 栏,当页面上下滚动时,它会出现和消失,但当用户在元素上滑动时它会保持静止touch-action: none。这是正确的行为。
我制作了一个测试页面,可以在其中重现该问题。尝试在 Safari 中的红色框上滑动手指,即使页面没有滚动,地址栏也会以动画方式进出。
我还在我的设备上制作了一个视频,在其中演示了 Chrome 没有这个问题,但 Safari 却有。
我在Apple 的 Safari 官方反馈表上提交了错误报告。与此同时,这个问题有解决方法吗?
我尝试了以各种不同的组合将height: 100%and添加overflow: hidden到htmland的常用方法,但没有任何帮助。body
试试这个打字稿代码:
let disableScroll = false;
let startY = 0;
function isScrollable(e: HTMLElement | null, up: boolean): boolean {
if (!e) return false;
if (up && e.scrollTop + e.clientHeight < e.scrollHeight) {
return true;
}
return e.scrollTop > 0;
}
function hasScrollableBase(e: HTMLElement | null, up: boolean) {
while (e && e !== document.body) {
e = e.parentNode as HTMLElement | null;
if (isScrollable(e, up)) return true;
}
return false;
}
function onTouchStart(e: TouchEvent) {
startY = e.touches[0].pageY;
disableScroll = false;
}
function onTouchMove(e: TouchEvent) {
const el =
e.target instanceof HTMLElement ? (e.target as HTMLElement) : null;
if (!el) {
e.preventDefault();
return false;
}
if (disableScroll || e.touches.length > 1) {
e.preventDefault();
return false;
}
const dy = e.touches[0].pageY - startY;
if (hasScrollableBase(el, dy < 0)) return true;
disableScroll = true;
e.preventDefault();
return false;
}
window.addEventListener("touchmove", onTouchMove, {
passive: false,
});
window.addEventListener("touchstart", onTouchStart);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2525 次 |
| 最近记录: |