uniapp根據導航欄的標題定位到相應錨點位置

小十的進階發表於2020-10-27

效果如圖:
在這裡插入圖片描述
封裝元件程式碼:
anchor-view/index.vue

<template>
  <view>
    <view
      :scrollTop="scrollTop"
      :minScolltop="minScolltop"
      :outermostView="outermostView"
      :types="types"
      class="anchor-view flex u-border-bottom"
    >
      <view
        v-for="(item,i) in types"
        class="flex-center wid-25 flex"
        v-text="item.title"
        :key="i"
        :id="item.anchor"
        :class="active === i? 'active':''"
        @click="changeActive(i)"
      ></view>
    </view>
  </view>
</template>

<script>
/**
 * @property {Number} minScolltop 你需要在滾動到多少時顯示這個介面
 * @property {Number} scrollTop 當前頁面的滾動距離
 * @property {String} outermostView 當前介面最外層的節點
 * @property {Array} types 你的錨點陣列
 */
export default {
  props: {
    minScolltop: {
      type: Number,
      default: 0
    },
    scrollTop: {
      type: Number,
      default: 0
    },
    outermostView: {
      type: String,
      default: '.contain-view'
    },
    types: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      active: 0
    }
  },
  methods: {
    changeActive(val) {
      this.active = val
      const _this = this
      for (let i = 0; i < _this.types.length; i++) {
        if (i === val) {
          uni
            .createSelectorQuery()
            .select(_this.types[i].anchor)
            .boundingClientRect(data => {
              // 目標位置節點 類或者 id
              uni
                .createSelectorQuery()
                .select('.contain-view')
                .boundingClientRect(res => {
                  // 最外層盒子節點類或者 id
                  uni.pageScrollTo({
                    duration: 0, // 過渡時間
                    scrollTop: data.top - res.top // 到達距離頂部的top值
                  })
                })
                .exec()
            })
            .exec()
          break
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.anchor-view {
  background-color: #FFFFFF;
  z-index: 998;
}
.wid-25 {
  color: #666666;
  position: relative;
}
// .active:after {
//   content: '';
//   position: absolute;
//   bottom: 2rpx;
//   width: 50rpx;
//   height: 6rpx;
//   background-color: #186de1;
//   right: 65%;
//   margin-right: -50rpx;
// }

.active:after {
  content: '';
      width: 42rpx;
      height: 0;
      border-bottom: 2px solid #007aff;
      position: absolute;
      left: 50%;
      bottom: 0;
      // -webkit-transform: translateX(-50%);
      transform: translateX(-50%);
      // -webkit-transition: .3s;
      transition: .3s;
}

.flex{
  white-space: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling:touch;
}
.flex-center{
  text-align: center;
  padding: 20rpx 32rpx;
  display: inline-block;
  // z-index: 20000;
  // background-color: pink;
}
</style>

頁面引用方法:
import anchorView from ‘@/components/anchor-view/index.vue’

<view class="nav-block">
	<anchor-view
	  :scrollTop="scrollTop"
	  :minScolltop="minScolltop"
	  :outermostView="outermostView"
	  :types="types"
	></anchor-view>
</view>

<view class="content-block self-collapse">
<!-- id對應types裡的anchor -->
	    <uni-collapse-item id="title" title="標題文字">
	        <view class="info">
	            手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果
	        </view>
	    </uni-collapse-item>
	    <uni-collapse-item id="title2" title="標題文字2">
	        <view class="info">
	            手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果手風琴效果
	        </view>
	    </uni-collapse-item>
	    <uni-collapse-item id="title3" title="標題文字3">
	        <view class="info">
	            手風琴效果手風琴效果手風琴效果
	        </view>
	    </uni-collapse-item>
	</uni-collapse>
</view>

import anchorView from '@/components/anchor-view/index.vue'
data() {
	return {
		 outermostView: '.contain-view',
		  minScolltop: 100, // 當滾動多少時,出現
		  scrollTop:180,
		  types: [
			{
			  title: '標題',
			  anchor: '#title'
			},
			{
			  title: '標題文字2',
			  anchor: '#title2'
			},
			{
			  title: '標題文字3',
			  anchor: '#title3'
			},
		  ]
		}
	},

相關文章