防止 iOS Safari 在不使用触摸操作时为其地址栏设置动画

Hri*_*dov 8 css safari ios

我已经在我的网站中实现了自定义触摸行为,并且使用触摸操作来防止浏览器处理用户手势。

问题是,当用户在带有 的元素上上下滑动时,Safari 将折叠并展开其底部的地址栏touch-action: none。内容不会滚动,这是预期的行为,但地址栏会更改其状态,但事实并非如此。这还会调整屏幕大小,导致布局变化和resize事件侦听器触发,并破坏用户体验。

Chrome 与 Safari 一样,底部也有一个 UI 栏,当页面上下滚动时,它会出现和消失,但当用户在元素上滑动时它会保持静止touch-action: none。这是正确的行为。

我制作了一个测试页面,可以在其中重现该问题。尝试在 Safari 中的红色框上滑动手指,即使页面没有滚动,地址栏也会以动画方式进出。

我还在我的设备上制作了一个视频,在其中演示了 Chrome 没有这个问题,但 Safari 却有。


我在Apple 的 Safari 官方反馈表上提交了错误报告。与此同时,这个问题有解决方法吗?

我尝试了以各种不同的组合将height: 100%and添加overflow: hiddenhtmland的常用方法,但没有任何帮助。body

iKB*_*AHT 0

试试这个打字稿代码:

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)