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>

结语

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

相关推荐
再学一点就睡3 小时前
手写 Promise 静态方法:从原理到实现
前端·javascript·面试
再学一点就睡4 小时前
前端必会:Promise 全解析,从原理到实战
前端·javascript·面试
前端工作日常4 小时前
我理解的eslint配置
前端·eslint
前端工作日常5 小时前
项目价值判断的核心标准
前端·程序员
90后的晨仔5 小时前
理解 Vue 的列表渲染:从传统 DOM 到响应式世界的演进
前端·vue.js
OEC小胖胖6 小时前
性能优化(一):时间分片(Time Slicing):让你的应用在高负载下“永不卡顿”的秘密
前端·javascript·性能优化·web
烛阴6 小时前
ABS - Rhomb
前端·webgl
植物系青年6 小时前
10+核心功能点!低代码平台实现不完全指南 🧭(下)
前端·低代码
植物系青年6 小时前
10+核心功能点!低代码平台实现不完全指南 🧭(上)
前端·低代码
桑晒.6 小时前
CSRF漏洞原理及利用
前端·web安全·网络安全·csrf