电梯导航----点击菜单--或者滚动区域---当前的菜单高亮-vue3--vue2
防止以后用到 作为模板参考
·
<template>
<div class="container">
<ul class="menu">
<li
v-for="item in list"
:key="item.key"
:class="{ active: item.key == current }"
@click="liClick(item.key)"
>
{{ item.name }}
</li>
</ul>
<div class="content">
<div id="key1">国家1</div>
<div id="key2">省份2</div>
<div id="key3">城市3</div>
<div id="key4">县城4</div>
<div id="key5">国家5</div>
<div id="key6">省份6</div>
<div id="key7">城市7</div>
<div id="key8">县城8</div>
<div id="key9">县城9</div>
<div id="key10">县城10</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, watchEffect } from "vue";
const current = ref("key1");
// const flag = ref(false);//----放开是另一种效果
const liClick = (key) => {
// flag.value = true;//----放开是另一种效果
current.value = key;
/*
获取到key 然后渠道对应的元素 进行滚动
*/
let content = document.querySelector(".content");
let target = document.querySelector(`#${key}`);
content.scrollTo({
top: target.offsetTop - 30,
behavior: "smooth",
});
};
const list = reactive([
{
key: "key1",
name: "国家1",
},
{
key: "key2",
name: "省份2",
},
{
key: "key3",
name: "城市3",
},
{
key: "key4",
name: "县城4",
},
{
key: "key5",
name: "国家5",
},
{
key: "key6",
name: "省份6",
},
{
key: "key7",
name: "城市7",
},
{
key: "key8",
name: "县城8",
},
{
key: "key9",
name: "县城9",
},
{
key: "key10",
name: "县城10",
},
]);
const showKeys = reactive([
// "ke1",
// "key2",
// "key3",
// "key4",
// "key5",
// "key6",
// "key7",
// "key8",
// "key9",
// "key10",
]);
// -----交叉观察器
let io = new IntersectionObserver(
(entrys) => {
console.log("进入视口--", entrys[0].target.id);
let firstInsetId = entrys[0].target.id;
let isInter = entrys[0].isIntersecting;
console.log(11111, isInter);
if (isInter) {
let isFind = showKeys.findIndex((item) => item == firstInsetId);
if (isFind == -1) {
showKeys.push(firstInsetId);
}
} else {
let index = showKeys.findIndex((item) => item == firstInsetId);
if (index !== -1) {
showKeys.splice(index, 1);
}
}
},
{ threshold: [0, 0.25, 0.5, 1] }
);
watchEffect(() => {
// if (flag.value) return;//----放开是另一种效果
let result = "";
for (const item of list) {
if (showKeys.findIndex((key) => key === item.key) !== -1) {
result = item.key;
break;
}
}
current.value = result;
});
console.log(watchEffect);
// ----初始话监听
const startObser = () => {
for (const item of list) {
let el = document.querySelector(`#${item.key}`);
showKeys.push(item.key);
io.observe(el);
}
};
onMounted(() => {
// let content = document.querySelector(".content");//----放开是另一种效果
// content.addEventListener("mouseenter", () => {//----放开是另一种效果
// console.log(123);
// flag.value = false;
// });
startObser();
});
</script>
<style lang="less" scoped>
.container {
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
justify-content: flex-start;
.menu {
margin-right: 5px;
width: 120px;
border: 1px solid pink;
padding: 0;
margin-bottom: 0;
li {
list-style: none;
height: 26px;
line-height: 26px;
font-size: 16px;
text-align: center;
cursor: pointer;
&:hover {
background-color: rgb(211, 14, 100);
}
}
li.active {
background-color: rgb(211, 14, 100);
}
}
.content {
width: calc(100% - 120px);
border: 1px solid red;
overflow-y: auto;
padding-top: 5px;
div {
height: 200px;
border: 1px solid rgb(0, 255, 21);
// margin-bottom: 3px;
}
}
}
</style>
下面这是稍微修改后的版本----去掉了监听---同时打开节流阀是在 鼠标滚动时 (上个版本是在鼠标移入时) -----对比上面的可
<template>
<div class="container">
<ul class="menu">
<li
v-for="item in list"
:key="item.key"
:class="{ active: item.key == current }"
@click="liClick(item.key)"
>
{{ item.name }}
</li>
</ul>
<div class="content">
<div id="key1">国家1</div>
<div id="key2">省份2</div>
<div id="key3">城市3</div>
<div id="key4">县城4</div>
<div id="key5">国家5</div>
<div id="key6">省份6</div>
<div id="key7">城市7</div>
<div id="key8">县城8</div>
<div id="key9">县城9</div>
<div id="key10">县城10</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onMounted, watchEffect } from "vue";
const current = ref("key1");
const flag = ref(false); //----放开是另一种效果
const liClick = (key) => {
flag.value = true; //----放开是另一种效果
current.value = key;
/*
获取到key 然后渠道对应的元素 进行滚动
*/
let content = document.querySelector(".content");
let target = document.querySelector(`#${key}`);
content.scrollTo({
top: target.offsetTop - 30,
behavior: "smooth",
});
};
const list = reactive([
{
key: "key1",
name: "国家1",
},
{
key: "key2",
name: "省份2",
},
{
key: "key3",
name: "城市3",
},
{
key: "key4",
name: "县城4",
},
{
key: "key5",
name: "国家5",
},
{
key: "key6",
name: "省份6",
},
{
key: "key7",
name: "城市7",
},
{
key: "key8",
name: "县城8",
},
{
key: "key9",
name: "县城9",
},
{
key: "key10",
name: "县城10",
},
]);
const showKeys = reactive([
// "ke1",
// "key2",
// "key3",
// "key4",
// "key5",
// "key6",
// "key7",
// "key8",
// "key9",
// "key10",
]);
// -----交叉观察器
let io = new IntersectionObserver(
(entrys) => {
console.log("进入视口--", entrys[0].target.id);
let firstInsetId = entrys[0].target.id;
let isInter = entrys[0].isIntersecting;
console.log(11111, isInter);
if (isInter) {
let isFind = showKeys.findIndex((item) => item == firstInsetId);
if (isFind == -1) {
showKeys.push(firstInsetId);
}
} else {
let index = showKeys.findIndex((item) => item == firstInsetId);
if (index !== -1) {
showKeys.splice(index, 1);
}
}
if (flag.value) return; //----放开是另一种效果
let result = "";
for (const item of list) {
if (showKeys.findIndex((key) => key === item.key) !== -1) {
result = item.key;
break;
}
}
current.value = result;
},
{ threshold: [0, 0.25, 0.5, 1] }
);
// watchEffect(() => {
// if (flag.value) return; //----放开是另一种效果
// let result = "";
// for (const item of list) {
// if (showKeys.findIndex((key) => key === item.key) !== -1) {
// result = item.key;
// break;
// }
// }
// current.value = result;
// });
console.log(watchEffect);
// ----初始话监听
const startObser = () => {
for (const item of list) {
let el = document.querySelector(`#${item.key}`);
showKeys.push(item.key);
io.observe(el);
}
};
onMounted(() => {
let content = document.querySelector(".content"); //----放开是另一种效果
content.addEventListener("mousewheel", () => {
//----放开是另一种效果
console.log(123);
flag.value = false;
});
startObser();
});
</script>
<style lang="less" scoped>
.container {
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
justify-content: flex-start;
.menu {
margin-right: 5px;
width: 120px;
border: 1px solid pink;
padding: 0;
margin-bottom: 0;
li {
list-style: none;
height: 26px;
line-height: 26px;
font-size: 16px;
text-align: center;
cursor: pointer;
&:hover {
background-color: rgb(211, 14, 100);
}
}
li.active {
background-color: rgb(211, 14, 100);
}
}
.content {
width: calc(100% - 120px);
border: 1px solid red;
overflow-y: auto;
padding-top: 5px;
div {
height: 200px;
border: 1px solid rgb(0, 255, 21);
// margin-bottom: 3px;
}
}
}
</style>
以看一下
vue2中的写法
<template>
<div class="main">
<ul class="nav">
<li @click="liClick(item.key)" :class="{active:currentKey==item.key}" v-for="item in navList" :key="item.key">{{ item.key }}</li>
</ul>
<div class="content">
<div :id="item.key" v-for="item in navList" :key="item.key">{{ item.name }}</div>
</div>
</div>
</template>
<script>
export default {
name: 'Play',
data () {
return {
flag:false,
currentKey:"key1",
navList: [
{name:"世界1",key:"key1"},
{name:"世界2",key:"key2"},
{name:"世界3",key:"key3"},
{name:"世界4",key:"key4"},
{name:"世界5",key:"key5"},
{name:"世界6",key:"key6"},
{name:"世界7",key:"key7"},
{name:"世界8",key:"key8"},
{name:"世界9",key:"key9"},
{name:"世界10",key:"key10"},
]
}
},
methods: {
liClick (key) {
this.flag=true
this.currentKey = key
// ---获取根元素
let content = document.querySelector(".content")
// ----获取目标元素
let targetEle = document.querySelector(`#${key}`)
content.scrollTo({
top: targetEle.offsetTop,
behavior: "smooth"
})
}
},
mounted () {
let ioInKey=[]
let option = {
threshold: [0, 0.25, 0.5, 0.75, 1],
}
const io = new IntersectionObserver((entrys) => {
let entrysOfFirst = entrys[0].target.id
if (entrys[0].isIntersecting) {
let find = ioInKey.findIndex(item => item == entrysOfFirst)
if (find == -1) {
ioInKey.push(entrysOfFirst)
}
} else {
let find = ioInKey.findIndex(item => item == entrysOfFirst)
if (find != -1) {
ioInKey.splice(find,1)
}
}
if(this.flag) return false
for (let item of this.navList){
const findItem= ioInKey.find(ite => ite == item.key)
if (findItem) {
this.currentKey = item.key
break
}
}
}, option);
this.navList.forEach(item => {
io.observe(document.querySelector(`#${item.key}`))
ioInKey.push(item.key)
})
// -----根元素绑定鼠标滚动事件---为了开始节流
let content = document.querySelector(".content")
content.addEventListener("mousewheel", () => {
this.flag=false
})
}
}
</script>
<style lang="scss" scoped>
*{
margin:0;
padding:0;
}
.main{
width:100%;
height:100%;
display:flex;
justify-content: flex-start;
.nav{
width:120px;
min-height:300px;
font-size:16px;
li{
height:26px;
line-height: 26px;
text-align:center;
background-color: pink;
&:hover,&.active{
background-color: rgb(108, 253, 5);
}
}
}
.content{
flex:1;
margin-left:5px;
width:calc(100%-120px);
height:700px;
overflow-y:auto;
border:1px solid rgb(0, 255, 8);
div{
height:300px;
border:1px solid blue;
}
}
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)