uniapp 兼容 H5 滚动

最近需要给 App 端适配 H5 界面,虽然平时调试都在电脑端浏览器中完成,原本觉得不会有太大问题。切换到移动端浏览器查看界面时,却发现部分布局无法滚动。而这在 uniapp 的文档中没有给出解决方案,查阅了一些博客才知道 Uniapp 在 H5 中限制了滚动,需要使用 <scroll-view> 容器进行包裹。

scroll-view 可滚动视图区域

scroll-view 主要用于区域滚动,使用这个容器需要遵循几个步骤。

  1. 指定 scroll-y="true" 或 scroll-x="true"
  2. 指定 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 样式完成,主要有两种方法:

  1. 使用 svw/svh 和 dvh/dvw
  2. 使用 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>

结语

目前笔者想到的适配方法只有这两种,如果您有更好的解决方法,欢迎补充。

相关推荐
怕浪猫6 小时前
FDE 如何正确解决现场项目工程性的问题
前端·后端·ai编程
西瓜太郎12346 小时前
外层模型卡片与分组详情成功率不一致,应该怎么排查?
前端·typescript·go·软件工程·react
GreenTea6 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
毕业设计7039 小时前
(免费领源码) 基于微信小程序的预制菜商城的设计与实现25172-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·python·mysql·微信小程序·pycharm·微信开发者工具·推荐算法
xifangge20259 小时前
AGENTS.md 怎么写?涵盖 Java、Python、Vue、Go 的 8 套开箱即用模板
java·vue.js·python
几何心凉9 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen9 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs10 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马11 小时前
从零到实战,完整AI学习路线
前端
三十而立洋11 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化