ios - 如何控制/禁用 IOS 中用于导航的滑动快照(JS)
问题描述
我的任务是修复我的 nextjs 应用程序中的一个讨厌的错误。本质上,当您在 IOS 上使用手指滑动浏览应用程序时,页面内容会闪烁。
据我所知,浏览器会在给定时间点拍摄堆和 dom 的快照。然后,一旦您想要导航回该页面,它会在您滑动时显示该快照。一旦您完成滑动并且浏览器认为页面已完成加载,它将停止显示快照并显示页面。
坦率地说,一旦快照停止显示,我已经放弃让快照实际匹配内容。我正在寻找的是一种禁用或控制显示为空白页的快照的方法。是的,它伤害了用户体验,但我的老板更喜欢它而不是闪存。
我已经在互联网上搜索了一个解决方案,现在我正在尝试通过 webkit 源代码来了解如何实现这一点。我知道这是可以实现的,因为 Instagram 已经实现了这一点。
如果您在 safari iOS 上访问 instagram.com 并尝试滑动手指进行导航,您会看到快照只是一个白页。
如果有人对如何做到这一点有任何见解,或者至少可以为我指明正确的方向,我将不胜感激。
谢谢!
解决方案
我能够通过浏览 webkit 源代码来解决这个问题。
第 225 行是加载快照图像的内容。因此,我们需要以某种方式让第 224 行中的条件评估为假。我发现的最简单的方法是得到这件作品:
shouldRestoreScrollPosition || (currentScrollPosition == snapshot->viewScrollPosition())
评估为假。第一部分shouldRestoreScrollPosition
由历史对象的 scrollRestoration 属性决定。浏览器对该属性的支持非常好,将其设置为手动将使您获得禁用图像快照的大部分方法。
只有一个问题,即该条件的第二部分。如果快照图像和窗口的滚动位置相同,scrollRestoration 将被忽略(因为它甚至不需要应用)。我使用了以下代码段,_app.tsx
其中似乎可以正常工作。
const alternator = React.useRef<number>(0);
// Scroll slightly and alternate between pages to always invalidate image snapshot.
// See {redacted} for explanation on this effect and the previous
React.useEffect(() => {
const slightScroll = () => {
if (IOS()) {
window.scrollTo({left: 0, top: alternator.current});
alternator.current = Number(!alternator.current);
}
};
router.events.on('routeChangeComplete', slightScroll);
return () => router.events.off('routeChangeComplete', slightScroll);
}, []);
这显然是一个非常 next.js 特定的片段,但想法是一样的。在向下滚动 1 个像素或不滚动之间交替,以确保在历史记录中前进或后退时滚动位置不同。
该解决方案并不完美(例如,在没有滚动的页面之间切换),但效果很好。此外,了解导致快照图像加载/不加载的确切条件意味着,如果有人看到这种情况需要改进我的解决方案,他们可以尝试其他方法使该条件评估为假或阻止线路执行更远(我个人尝试在页面之间更改设备规模的标题但无济于事)。
希望这可以避免我不得不经历的挫败感:)
推荐阅读
- sass - Sass vs Scss - 我应该如何搜索 SASS?
- xml - 如何指定 xslt 所针对的 xml 文件的命名空间?
- python - Django过滤多个数组列表值
- javascript - 如何将我的 JavaScript 函数链接到 HTML 元素?
- sql-server - 强制 Excel 使用 SQL 查询运行宏
- postgresql - psql:致命:“用户名”角色不可用
- sql - 外键在表中显示为 NULL。为什么?
- excel - 将 UserForm textbox.value 作为日期格式传输到工作表
- r - 通过动态选择名称来组合多个数据框
- rabbitmq - MassTransit/RabbitMQ 发送与发布和故障<> 问题