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

发布于 2025-01-18 09:31:41 字数 1006 浏览 2 评论 0原文

我已经在我的网站中实现了自定义触摸行为,并且正在使用 touch -action 阻止浏览器处理用户手势。

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

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

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

我还在我的设备上制作了一个视频,我在其中演示了 Chrome 为何不具备该功能问题,但 Safari 确实如此。


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

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

I have implemented custom touch behavior in my site and I'm using touch-action to prevent the browser from handling user gestures.

The problem is that Safari will collapse and expand its address bar at the bottom as the user is swiping up and down over an element with touch-action: none. The content isn't scrolled, which is the expected behavior, but the address bar changes its state, which isn't. This also resizes the screen, causes layout shifts and resize event listeners to fire, and ruins the user experience.

Chrome, like Safari, also has a UI bar at the bottom that appears and disappears when the page is scrolled up and down, but it stays still while the user swipes over a touch-action: none element. This is the correct behavior.

I've made a test page where the issue can be reproduced. Try swiping fingers over the red box in Safari and the address bar should animate in and out, even though the page isn't scrolling.

I've also made a video on my device, where I demonstrate how Chrome doesn't have that issue, but Safari does.


I filed a bug report on Apple's official feedback form for Safari. In the meantime, is there a workaround for the issue?

I tried the usual approach of adding height: 100% and overflow: hidden to html and body, in various different combinations, but nothing helped.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单调的奢华 2025-01-25 09:31:41

试试这个打字稿代码:

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);

Try this typescript code:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文