The issue you're encountering with collapsing when scrolling or swiping down in the Telegram Web App is a common problem. Having faced a similar issue myself, I've discovered a solution that effectively resolves it.
Visual Comparsion:
Before diving into the solution, let's visually observe the problem. Below are two GIFs illustrating the issue before and after implementing the solution.
|
|
Bug Swiping down the Telegram Mini App causes it to collapse instead of scrolling* |
Fixed Swiping down the Telegram Mini App now correctly scrolls through the content after the issue is fixed!* |
Now that we've seen the issue in action, let's proceed to implement the solution. I'll provide a step-by-step guide to resolve the problem.
Step-by-Step Solution:
1. Ensure the Document is Scrollable:
Firstly, it's essential to ensure that the document is scrollable. We achieve this by checking if the document's scroll height is greater than the viewport height. If not, we adjust the document's height accordingly.
// 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. Prevent window.scrollY
from Becoming Zero:
Next, we prevent window.scrollY
from becoming zero when swiping down on the scrollable element. This prevents unexpected collapses when swiping down.
// 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);
Now that we've outlined the steps, let's integrate the solution into your code. Below is the full code snippet. I've removed unnecessary code and styles to understand the code better.
<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>
By implementing these adjustments, your Telegram Mini App will no longer suffer from unexpected collapses when scrolling for swiping down.
I encourage you to deploy the provided code for a Telegram Web App and observe the results firsthand.
Additionally, you can experience the fix in action on a Telegram Mini App I've applied this solution to: @theme_inspector_bot