uniapp设置安全区

一、需求:

我们有一个uniapp开发的H5,需要嵌入第三方的APP中,但是状态栏文字(如时间、信号、电池)遮挡导航栏内容,如图所示


需要做到:
1.导航栏始终处于页面最顶端
2.导航栏不能遮挡状态栏

如图所示

二、解决方式

1.引入安全区概念,会自动获取状态栏高度

javascript 复制代码
  onLoad() {
    uni.getSystemInfo({
      success: (result) => {
      	//获取安全区距离并存入本地
        uni.setStorageSync('statusBarHeight', result.statusBarHeight)
      }
    })
  },

2.导航栏高度=本身高度(40px)+安全区高度。 再设置padding-top=安全区高度。这样导航栏始终处于状态栏之下

javascript 复制代码
<!-- 安全区域占位 -->
    <view class="navbar-container" :style="{
      height: (statusBarHeight + 40) + 'px', // 安全区高度 + 导航栏高度
      paddingTop: statusBarHeight + 'px' // 导航栏内容避开安全区
    }">
      <view class="navbarBox">
        <u-icon name="arrow-left" color="#2979ff" size="28" @click="goBack"></u-icon>
        <p>短信与任务</p>
        <view class="placeholder"></view>
      </view>
    </view>

3.设置导航栏固定位置

javascript 复制代码
.navbar-container {
  position: fixed; // 关键:固定定位,不随滚动移动
  top: 0;
  left: 0;
  right: 0;
  background: rgb(148, 194, 247); // 和页面背景一致,避免穿透
  z-index: 999; // 确保导航栏在最上层,不被内容覆盖
  box-sizing: border-box;
  padding: 0 10px; // 和页面容器的padding对齐,避免导航栏内容偏移
}

4.将滚动区域设置高度

javascript 复制代码
    <view class="content-container" :style="{
      height: `calc(100vh - ${statusBarHeight + 40}px)`, // 动态减去导航栏总高度
      marginTop: `${statusBarHeight + 40}px` // 顶部间距=导航栏总高度,双重保险
    }">
      <u-list @scrolltolower="scrolltolower">
        <u-list-item v-for="(item, index) in indexList" :key="index">
          <u-cell :title="`列表长度-${index + 1}`">
            <u-avatar slot="icon" shape="square" size="35" :src="item.url"
              customStyle="margin: -3px 5px -3px 0"></u-avatar>
          </u-cell>
        </u-list-item>
      </u-list>
    </view>

三、提示+完整代码

1.提示:源码使用了Uview组件(地址),可删除或自行引入

2.源码

javascript 复制代码
<template>
  <view class="u-page">
    <!-- 安全区域占位 -->
    <view class="navbar-container" :style="{
      height: (statusBarHeight + 40) + 'px', // 安全区高度 + 导航栏高度
      paddingTop: statusBarHeight + 'px' // 导航栏内容避开安全区
    }">
      <view class="navbarBox">
        <u-icon name="arrow-left" color="#2979ff" size="28" @click="goBack"></u-icon>
        <p>短信与任务</p>
        <view class="placeholder"></view>
      </view>
    </view>
    <view class="content-container" :style="{
      height: `calc(100vh - ${statusBarHeight + 40}px)`, // 动态减去导航栏总高度
      marginTop: `${statusBarHeight + 40}px` // 顶部间距=导航栏总高度,双重保险
    }">
      <u-list @scrolltolower="scrolltolower">
        <u-list-item v-for="(item, index) in indexList" :key="index">
          <u-cell :title="`列表长度-${index + 1}`">
            <u-avatar slot="icon" shape="square" size="35" :src="item.url"
              customStyle="margin: -3px 5px -3px 0"></u-avatar>
          </u-cell>
        </u-list-item>
      </u-list>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      //安全区距离
      statusBarHeight: JSON.parse(uni.getStorageSync("statusBarHeight")),

      indexList: [],
      urls: [
        "https://uviewui.com/album/1.jpg",
        "https://uviewui.com/album/2.jpg",
        "https://uviewui.com/album/3.jpg",
        "https://uviewui.com/album/4.jpg",
        "https://uviewui.com/album/5.jpg",
        "https://uviewui.com/album/6.jpg",
        "https://uviewui.com/album/7.jpg",
        "https://uviewui.com/album/8.jpg",
        "https://uviewui.com/album/9.jpg",
        "https://uviewui.com/album/10.jpg",
      ],
    }
  },

  onLoad() {
    uni.getSystemInfo({
      success: (result) => {
        uni.setStorageSync('statusBarHeight', result.statusBarHeight)
        console.log(JSON.parse(uni.getStorageSync("statusBarHeight")), 666);
      }
    })
    this.loadmore();

  },
  methods: {
    scrolltolower() {
      this.loadmore();
    },
    loadmore() {
      for (let i = 0; i < 30; i++) {
        this.indexList.push({
          url: this.urls[uni.$u.random(0, this.urls.length - 1)],
        });
      }
    },
    //返回上一页
    goBack() {
    },
  }
}
</script>

<style lang="scss" scoped>
.u-page {
  padding: 10px;
  background: rgb(249, 250, 251);
  min-height: 100%;
  box-sizing: border-box;
}

// 固定导航栏容器:固定在顶部,覆盖安全区
.navbar-container {
  position: fixed; // 关键:固定定位,不随滚动移动
  top: 0;
  left: 0;
  right: 0;
  background: rgb(148, 194, 247); // 和页面背景一致,避免穿透
  z-index: 999; // 确保导航栏在最上层,不被内容覆盖
  box-sizing: border-box;
  padding: 0 10px; // 和页面容器的padding对齐,避免导航栏内容偏移
}

.navbarBox {
  height: 40px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
}

.placeholder {
  width: 28px;
  height: 28px;
}

.navbarBox p {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
}

.content-container {
  width: 100%;
  box-sizing: border-box;
  overflow-y: auto;
  padding-top: 10px; // 可选:给列表顶部加少量内边距,避免紧贴导航栏底部
}
</style>
相关推荐
汤姆Tom4 分钟前
CSS 预处理器深入应用:提升开发效率的利器
前端·css·面试
练习前端两年半5 分钟前
Vue3组件二次封装终极指南:动态组件+h函数的优雅实现
前端·vue.js
aricvvang12 分钟前
🚀 NestJS 使用 cache-manager-redis-store 缓存无效?真相在这里!
javascript·后端·nestjs
2501_9151063213 分钟前
HTTPS 爬虫实战指南 从握手原理到反爬应对与流量抓包分析
爬虫·网络协议·ios·小程序·https·uni-app·iphone
皮皮虾我们跑13 分钟前
前端HTML常用基础标
前端·javascript·html
2501_9160074713 分钟前
iOS 上架技术支持全流程解析,从签名配置到使用 开心上架 的实战经验分享
android·macos·ios·小程序·uni-app·cocoa·iphone
Yeats_Liao14 分钟前
Go Web 编程快速入门 01 - 环境准备与第一个 Web 应用
开发语言·前端·golang
卓码软件测评14 分钟前
第三方CMA软件测试机构:页面JavaScript动态渲染生成内容对网站SEO的影响
开发语言·前端·javascript·ecmascript
Mintopia17 分钟前
📚 Next.js 分页 & 模糊搜索:在无限数据海里优雅地翻页
前端·javascript·全栈
Mintopia18 分钟前
⚖️ AIGC版权确权技术:Web内容的AI生成标识与法律适配
前端·javascript·aigc