Uniapp实现页面滚动Tab吸顶,点击tab内容滚动到对应tab内容位置

思路:运用uniapp原生提供方法uni.createSelectorQuery()获取滚动对应节点的信息,即节点距离页面顶部的距离,再通过uniapp原生监听页面滚动事件onPageScroll,获取页面内容滚动的高度,二者相加即定位到对应节点的滚动距离。

1.template结构

javascript 复制代码
    <view class="content-tabs-box">
      <view class="content-tabs" :class="{'is-fixed': isTabFixed}">
        <view
          v-for="(item, index) in detailTabs" :key="index" 
          class="tab" :class="{'active': curTab === index}" @click="scrollTo(index, item.className)">
          {{item.name}}
        </view>
      </view>
    </view>
     <!-- 正文详情 -->
    <view class="library-detail-content">
      <view v-if="libraryDetail.videoUrl" class="content-msg">
        <video :src="libraryDetail.videoUrl" autoplay style="width: 100%;" />
      </view>
      <view v-else class="content-msg" v-html="libraryDetail.content"></view>
    </view>
    <!-- 相关附件 -->
    <view v-if="attachment.length > 0" class="library-detail-attachment">
      <view class="attachment-box">
        <view class="title">相关附件</view>
      </view>
      <view class="attachment-list-box">
        <view v-for="(item, index) in attachment" :key="index" class="attchment-list">
          <view class="list-name">{{ item.name }}</view>
          <view class="download-btn" @click="download(item.url)">
            <image src="@/static/images/allPolicy/download-btn.png" style="width: 35rpx;height: 36rpx;margin-right: 10rpx;" mode="scaleToFill" />
            <view>下载</view>
          </view>
        </view>
      </view>
    </view>
    <!-- 图文解读 -->
    <view v-if="relatedPosts.length > 0" class="library-detail-relatedPosts">
      <view class="attachment-box">
        <view class="title">图文解读</view>
      </view>
      <view class="attachment-list-box">
        <view v-for="(item, index) in relatedPosts" :key="index" @click="toWebView(item.url, item.title)" class="attchment-list">
          <view><span style="margin-right: 20rpx;">{{ postType(item.related_classify) }}</span> {{ item.title }}</view>
        </view>
      </view>
    </view> 

2.定义变量

javascript 复制代码
  data() {
    return {
      curTab: 0,
      isTabFixed: false,
      tabTop: 0,  // tab距离顶部的距离
      curClassName: '',
      pageScrollTop: 0
    }
  },
  computed() {
    detailTabs() {
      let tabs = [{
        name: '正文详情',
        className: '.library-detail-content'
      }]
      if(this.attachment && this.attachment.length > 0) {
        tabs.splice(1, 0, {
          name: '相关附件',
          className: '.library-detail-attachment'
        })
      }
      if(this.relatedPosts && this.relatedPosts.length > 0) {
        tabs.splice(2, 0, {
          name: '图文解读',
          className: '.library-detail-relatedPosts'
        })
      }
      return tabs
    },
  }

3.方法定义

javascript 复制代码
// 点击tab滚动事件
  scrollTo(tab, className) {
      if(!className) return
      if(this.curClassName == className) return
      this.curTab = tab
      const query = uni.createSelectorQuery().in(this);
      query.select(className).boundingClientRect(data => {
        uni.pageScrollTo({
          scrollTop: className == '.library-detail-content' ? 0 : (data?.top + ((this.pageScrollTop || 0))),
          duration: 300
        })
      }).exec();

      this.curClassName = className
    },

// uni页面滚动监听事件
  onPageScroll(e) {
    // 获取tabs的距离顶部的距离
    this.tabTop = uni.createSelectorQuery().select('.content-tabs').boundingClientRect(data => {
      this.tabTop = data.top;
      this.isTabFixed = (e.scrollTop > this.tabTop)
      this.pageScrollTop = e.scrollTop
    }).exec();
  },

4.实现效果

相关推荐
Coffeeee6 分钟前
从 Android 15 到 Android 17,谷歌猝不及防的音频改动
android·前端·google
雪隐13 分钟前
用Flutter做背单词APP-00前言
前端·人工智能·后端
何时梦醒14 分钟前
前端存储全攻略 & JavaScript this 绑定完全指南
前端·javascript·面试
前端百草阁17 分钟前
JavaScript 设计模式(23 种)
开发语言·前端·javascript·设计模式
用户693717500138422 分钟前
AI 领域的 Harness,到底是什么意思?
android·前端·后端
spider_xcxc28 分钟前
Redis 深度实践:安全管控、性能压测与持久化分析(二)
运维·前端·redis·云计算·bootstrap·运维开发
乘风gg28 分钟前
代码都已经让 AI 写了,为什么有些人却更慌了?
前端·ai编程·claude
我不是外星人39 分钟前
一键还原任意网站,这套 Playwright + 多 Agent 工程流太猛了
前端·后端·ai编程
用户0595401744643 分钟前
AI 客服突然“失忆”,排查 6 小时发现 LangChain 记忆存储的 3 个致命坑
前端·css
IT_陈寒1 小时前
Vue的v-if和v-show,我竟然用错了这么久
前端·人工智能·后端