用vue写一个随着滚动高度 而高亮的效果

分别在hbuilder中 和vscode中写一套代码

滑动高亮


上效果图

1. 在hbuilder中 小程序的代码

<template>
	<view  class="">
		<view class="detailNavbar" :style="[{ height: navbar - sys_statusBar + 'px',opacity: tabOpacityVal  }]">
			<view @tap="onTab(item)" class="navbar-item" :class="curTab === item.value ? 'current' : ''"
				v-for="item in tabList" :key="item.to">
				{{item.label}}
			</view>
		</view>

		<view class="detail-swiper-selecto">

		</view>
		<view class="detail-comment-selector">

		</view>
		<view class="detail-content-selector">

		</view>
	</view>
</template>

<script setup>
	import {
		onLoad,
		onShow,
		onPageScroll
	} from '@dcloudio/uni-app'
	import throttle from "@/utils/throttle.js"
	import {
		ref
	} from "vue";
	const curTab = ref('goods')
	const tabOpacityVal = ref(0)
	const tabList = ref([{
			label: '商品',
			value: 'goods',
			to: 'detail-swiper-selector',
		},
		{
			label: '评价',
			value: 'comment',
			to: 'detail-comment-selector',
		},
		{
			label: '详情',
			value: 'detail',
			to: 'detail-content-selector',
		},
	])
	// 设备信息
	const device = uni.getSystemInfoSync();

	// 标题栏高度
	const getNavBar = () => {
		return device.statusBarHeight + 44;
	};
	const navbar = getNavBar();
console.log('divce',device);
	const sys_statusBar = device.statusBarHeight

	let commentCard = {
		top: 0,
		bottom: 0,
	};
	// 点击跳转到对应的位置
	const onTab = (item) => {
		let scrollTop = 0;
		if (item.value === 'comment') {
			scrollTop = commentCard.top - navbar + 1;
		} else if (item.value === 'detail') {
			scrollTop = commentCard.bottom - navbar + 1;
		}
		console.log(scrollTop);
		uni.pageScrollTo({
			scrollTop,
			duration: 200,
		});
	}

	// 获取评论区的top值 和详情区的bottom
	const getCommentCardNode = () => {
		return new Promise((res, rej) => {
			uni.createSelectorQuery()
				.select('.detail-comment-selector')
				.boundingClientRect((data) => {
					if (data) {
						commentCard.top = data.top;
						commentCard.bottom = data.top + data.height;
						res(data);
					} else {
						res(null);
					}
				})
				.exec();
		});
	}

	onPageScroll((e) => {
		// 判断是否需要透明
		tabOpacityVal.value = e.scrollTop > navbar ? 1 : e.scrollTop * 0.01;
		// 获取评论区的top值 和详情区的bottom
		if (commentCard.top === 0) {
			throttle(() => { //节流函数
				getCommentCardNode();
			}, 50);
		}
		if (e.scrollTop < commentCard.top - navbar) {
			// 滑动的距离小于评论区的顶部时
			curTab.value = 'goods';
		} else if (
			e.scrollTop >= commentCard.top - navbar &&
			e.scrollTop <= commentCard.bottom - navbar
		) {
			// 滑动的距离大于评论区顶部 小于评论区底部时
			curTab.value = 'comment';
		} else {
			curTab.value = 'detail';
		}

	})


	

	const updateTheme = () => {

	}
</script>

<style scoped lang="scss">
	.detailNavbar {
		position: fixed;
		top: 0;
		color: #000;
		background-color: #fff;
		width: 100%;
		// height: ;
		display: flex;
		align-items: center;
		justify-content: center;

		.navbar-item {
			flex: 1;
			text-align: center;
		}

		.current {
			color: red;
		}
	}

	.detail-swiper-selecto {
		height: 100vh;
		width: 100%;
		background-color: red;
	}

	.detail-comment-selector {
		height: 30vh;
		width: 100%;
		background-color: blue;
	}

	.detail-content-selector {
		height: 100vh;
		width: 100%;
		background-color: green;
	}
</style>

2. 在h5中用vscode的代码

<template>
  <!-- 滑动效果  手机版 -->
  <div id="scroll-container" ref="scrollref">
    <div class="detailNavbar" :style="[{ height:navbarHeight + 'px',opacity: tabOpacityVal  }]">
      <div @click="onTab(item)" class="navbar-item" :class="curTab === item.value ? 'current' : ''"
        v-for="item in tabList" :key="item.to">
        {{item.label}}
      </div>
    </div>

    <div class="detail-swiper-selector">

    </div>
    <div class="detail-comment-selector">

    </div>
    <div class="detail-content-selector">

    </div>
  </div>
</template>

<script setup>
  import throttle from "@/utils/throttle.js"
  import {
    ref,
    onMounted,
    nextTick
  } from "vue";
  const curTab = ref('goods')
  const tabOpacityVal = ref(0)
  const tabList = ref([{
      label: '商品',
      value: 'goods',
      to: 'detail-swiper-selector',
    },
    {
      label: '评价',
      value: 'comment',
      to: 'detail-comment-selector',
    },
    {
      label: '详情',
      value: 'detail',
      to: 'detail-content-selector',
    },
  ])
  const scrollref = ref(null)
  const navbarHeight = 44
  onMounted(() => {
    // const container = document.getElementById('scroll-container');
    // const container = document.getElementById('scroll-container');
    // 添加滚动事件监听器
    // console.log(container);
    nextTick(() => {
      scrollref.value.addEventListener('scroll', onPageScroll, true);
    })
  })
  let commentCard = {
    top: 0,
    bottom: 0,
  };
  // 点击跳转到对应的位置
  const onTab = (item) => {
    let scrollTop = 0;
    if (item.value === 'comment') {
      scrollTop = commentCard.top - navbarHeight + 1;
    } else if (item.value === 'detail') {
      scrollTop = commentCard.bottom - navbarHeight + 1;
    }
    console.log(scrollTop);

    // window.scrollTo({
    //   top: scrollTop,
    //   behavior: "smooth",
    // });
    //上面的方法在设置 overflow: scroll;后不能使用 原因未知  下面的两种方法都能使用
    scrollref.value.scrollTop = scrollTop
    // const scrolDom = document.querySelector(`.${item.to}`)
    // scrolDom.scrollIntoView({
    //   behavior: 'smooth' // 加一个过渡动画(固定的)
    // })

  }

  // 获取评论区的top值 和详情区的bottom
  const getCommentCardNode = () => {
    return new Promise((res, rej) => {
      let elem = document.querySelector(".detail-comment-selector");
      let rect = elem.getBoundingClientRect();
      console.log(rect);
      if (rect) {
        commentCard.top = rect.top;
        commentCard.bottom = rect.top + rect.height;
        res(rect)
      } else {
        res(null)
      }

    });
  }

  const onPageScroll = (e) => {
    // console.log(e.target.scrollTop);
    // 判断是否需要透明
    const scrollTop = e.target.scrollTop
    tabOpacityVal.value = scrollTop > navbarHeight ? 1 : scrollTop * 0.01;
    // 获取评论区的top值 和详情区的bottom
    if (commentCard.top === 0) {
      throttle(() => { //节流函数
        getCommentCardNode();
      }, 50);
    }
    if (scrollTop < commentCard.top - navbarHeight) {
      // 滑动的距离小于评论区的顶部时
      curTab.value = 'goods';
    } else if (
      scrollTop >= commentCard.top - navbarHeight &&
      scrollTop <= commentCard.bottom - navbarHeight
    ) {
      // 滑动的距离大于评论区顶部 小于评论区底部时
      curTab.value = 'comment';
    } else {
      curTab.value = 'detail';
    }
  }
</script>

<style scoped lang="scss">
  #scroll-container {
    width: 100%;
    height: 100vh;
    // overflow-y: auto;
    overflow: scroll;
    scroll-behavior: smooth ;
  }

  .detailNavbar {
    position: fixed;
    top: 0;
    color: #000;
    background-color: #fff;
    width: 100%;
    // height: ;
    display: flex;
    align-items: center;
    justify-content: center;

    .navbar-item {
      flex: 1;
      text-align: center;
    }

    .current {
      color: red;
    }
  }

  .detail-swiper-selector {
    height: 100vh;
    width: 100%;
    background-color: red;
  }

  .detail-comment-selector {
    height: 30vh;
    width: 100%;
    background-color: blue;
  }

  .detail-content-selector {
    height: 100vh;
    width: 100%;
    background-color: green;
  }
</style>```

你可能感兴趣的:(vue.js,前端,javascript)