最近需要给 App 端适配 H5 界面,虽然平时调试都在电脑端浏览器中完成,原本觉得不会有太大问题。切换到移动端浏览器查看界面时,却发现部分布局无法滚动。而这在 uniapp 的文档中没有给出解决方案,查阅了一些博客才知道 Uniapp 在 H5 中限制了滚动,需要使用 <scroll-view>
容器进行包裹。
scroll-view 可滚动视图区域
scroll-view 主要用于区域滚动,使用这个容器需要遵循几个步骤。
- 指定 scroll-y="true" 或 scroll-x="true"
- 指定 scroll-view 的固定高度,一般指定 width: 100vw 或 height: 100vh
html
<scroll-view scroll-x="true" style="height:100vw">
...
</scroll-view>
<!-- OR -->
<scroll-view scroll-y="true" style="height:100vh">
...
</scroll-view>
但是,使用 100vh 对于部分布局可能造成一些问题,笔者在兼容一些界面设置为 100vh 时,出现界面卡顿的情况,不能一次性流畅的滚动到顶部和底部。所以这个时候,我们可以手动为其设置动态高度。
scroll-view 设置动态高度
scroll-view 的高度主要还是通过更改 CSS 样式完成,主要有两种方法:
- 使用 svw/svh 和 dvh/dvw
- 使用 JavaScript 在布局加载完成后,获取 window.innerHeight(浏览器窗口的视口高度),然后赋值给 scroll-view
使用 svw/svh 和 dvh/dvw
svw/svh 和 dvh/dvw 是 CSS 中的一个新的布局单位,其使用方法和 vh/vw 一致。
CSS 单位 | 相对于 | 说明 |
---|---|---|
dvh | 动态视口高度的 1% | 动态视口高度 (Dynamic Viewport Height),表示当前可视区域高度的 1%。它会自动适应浏览器 UI 的显隐变化,解决了传统 100vh 在移动设备上可能出现的问题 |
dvw | 动态视口宽度的 1% | 动态视口宽度 (Dynamic Viewport Width),表示当前可视区域宽度的 1%,能够随着浏览器窗口的动态变化而调整 |
svh | 小视口高度的 1% | 小视口高度(Small Viewport Height)的缩写,用于解决在移动设备上使用 100vh 时可能出现的溢出问题。在基于小视口大小的百分比单位高度下,确保了浏览器 UI 最大化时,网站内容不会溢出屏幕。 |
svw | 小视口宽度的 1% | 小视口宽度的 1%,在小视口环境下,为布局提供相对宽度单位,使页面在小屏幕设备上有更好的自适应性 |
有了 CSS 提供的视口单位,我们只需要将其设置为 100,布局的高度就会进行自适应。
html
<scroll-view scroll-x="true" style="height:100svw">
...
</scroll-view>
<!-- OR -->
<scroll-view scroll-y="true" style="height:100svh">
...
</scroll-view>
html
<scroll-view scroll-x="true" style="height:100dvw">
...
</scroll-view>
<!-- OR -->
<scroll-view scroll-y="true" style="height:100dvh">
...
</scroll-view>
但是因为是新特性,使用前还需要考虑兼容性。从 MDN 给出的兼容性文档来看,对于 svw/svh 和 dvh/dvw 在部分浏览器内核中的支持性并不明确,并不能完全适配所有设备。


不过如果你的场景只在主流浏览器中,那么这个特性是个很好的选择。也许再过一段时间后,这个特性就能得到很好的支持。
JavaScript 设置浏览器视口高度
在浏览器中,可以通过 window.innerHeight 获取浏览器窗口的视口高度,因此我们可以在布局加载完成之后手动设置布局的高度。
html
<template>
<scroll-view scroll-y="true" class="scrollView">
...
</scroll-view>
<!--
<scroll-view scroll-x="true" class="scrollView">
...
</scroll-view>
-->
</template>
<script lang="ts" setup>
import { onMounted } from "vue";
onMounted(async () => {
// #ifdef H5
setPageFullHeight();
// #endif
});
// #ifdef H5
function setPageFullHeight() {
const page = document.querySelector(".scrollView");
const height = window.innerHeight;
page.style.height = `${height}px`;
}
// #endif
</script>
<style lang="sass" scoped>
.scrollView{
height: 100vh;
//width: 100vw;
}
</style>
结语
目前笔者想到的适配方法只有这两种,如果您有更好的解决方法,欢迎补充。