Telegram Bot 的 Web 应用程序中滚动时出现折叠错误
我想在 Telegram 中构建用 Flutter 编写的移动 Web 应用程序。同时,存在一个问题:向下滚动时,应用程序会折叠,就像我正在折叠底部工作表一样。
Web App ; Telegram Web App ; 问题的视频演示
我设法通过在代码中添加以下脚本来解决 iOS 设备上的这个问题:
document.addEventListener("touchmove", function (event) {
event.preventDefault();
},
{
passive: false
});
但在 Android 上,问题仍然存在。我尝试了使用 touchmove、overflow、relative 和其他方法来禁用页面上的滚动的所有变体。我找到的所有方法都无法解决 Android 上的问题。
将其添加到 css 中的 body 部分以禁用任何触摸事件:
body {
touch-action: none !important;
}
您在 Telegram Web App 中滚动或向下滑动时遇到的折叠问题是一个常见问题。我自己也遇到过类似的问题,我发现了一个有效解决该问题的解决方案。
视觉比较:
在深入研究解决方案之前,让我们直观地观察一下这个问题。下面是两个 GIF,分别展示了实施解决方案前后的问题。
现在我们已经看到了问题的实际效果,让我们继续实施解决方案。我将提供解决问题的分步指南。
分步解决方案:
1.确保文档可滚动:
首先,必须确保文档可滚动。我们通过检查文档的滚动高度是否大于视口高度来实现这一点。如果不大于,我们将相应地调整文档的高度。
// Ensure the document is scrollable
function ensureDocumentIsScrollable() {
const isScrollable =
document.documentElement.scrollHeight > window.innerHeight;
// Check if the document is scrollable
if (!isScrollable) {
/*
Set the document's height to 100 % of
the viewport height plus one extra pixel
to make it scrollable.
*/
document.documentElement.style.setProperty(
"height",
"calc(100vh + 1px)",
"important"
);
}
}
// Call ensureDocumentIsScrollable function when the entire page has loaded.
window.addEventListener("load", ensureDocumentIsScrollable);
2. 防止
window.scrollY
变为零:
接下来,我们防止在可滚动元素上向下滑动时
window.scrollY
变为零。这可以防止向下滑动时意外折叠。
// Prevent windwo.scrollY from becoming zero
function preventCollapse(event) {
if (window.scrollY === 0) {
window.scrollTo(0, 1);
}
}
// Attach the above function to the touchstart event handler of the scrollable element
const scrollableElement = document.querySelector(".scrollable-element");
scrollableElement.addEventListener("touchstart", preventCollapse);
现在我们已经概述了步骤,让我们将解决方案集成到您的代码中。以下是完整的代码片段。我删除了不必要的代码和样式,以便更好地理解代码。
<html>
<head>
<style>
.scrollable-element {
overflow-y: scroll;
height: 32rem;
font-size: 6.25rem;
border: 1px solid;
}
</style>
</head>
<body>
<div class="scrollable-element">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
<script>
function ensureDocumentIsScrollable() {
const isScrollable =
document.documentElement.scrollHeight > window.innerHeight;
if (!isScrollable) {
document.documentElement.style.setProperty(
"height",
"calc(100vh + 1px)",
"important"
);
}
}
function preventCollapse() {
if (window.scrollY === 0) {
window.scrollTo(0, 1);
}
}
const scrollableElement = document.querySelector(".scrollable-element");
scrollableElement.addEventListener("touchstart", preventCollapse);
window.addEventListener("load", ensureDocumentIsScrollable);
</script>
</body>
</html>
通过实施这些调整,您的 Telegram Mini App 在向下滚动时将不再遭受意外崩溃。
我鼓励您为 Telegram Web App 部署提供的代码并亲自观察结果。
此外,您可以在 Telegram Mini App 上体验修复效果,我已将此解决方案应用于: @theme_inspector_bot
共有3个步骤:添加样式、添加滚动和添加延迟
-
在 index.html 中的 head 标签下添加此样式:
<style> body { height: 1000vh !important; position: static !important; overscroll-behavior: none; } flutter-view { position: fixed !important; max-width: 100vw !important; max-height: 100vh !important; } /* Safari 特定的 CSS */ @supports (-webkit-touch-callout: inherit) { body { height: 1000vh !important; } } </style>
- 在 index.html 中的 body 标签下添加滚动脚本:
<script>window.scroll(0, window.document.body.scrollHeight);</script>
-
(可选)有时 Telegram 加载速度不快,因此在 ma​​in.dart 中添加一些延迟:
void main() async { await Future.delayed(const Duration(milliseconds: 500)); }
您可以关注类似的 github 问题 此处