QQ20241211-15176
public/index.js文件
// 判断元素是否可见
export function elVisible(fn = () => null, config = {}) {
// console.log(fn,'fn')
// visible = true 元素不可见时也返回事件,否则我只需要元素可见时触发
// threshold = 0 监听元素出现交叉就触发 / = 1 元素必须完全出现才触发 / = 0.5 元素出现一半就触发
// rootMargin 扩张 向内或向外扩张交叉区域
let { visible = false, ...rest } = config;
let configs = { threshold: 0, rootMargin: "-50%", ...rest };
const observe = entries => {
for (const { isIntersecting = false, target = {} } of entries) {
// created && created(target);
if (visible) {
fn && fn(target, isIntersecting)
} else {
isIntersecting && fn && fn(target, isIntersecting, subsidiary)
};
};
};
let subsidiary = new IntersectionObserver(observe, configs);
const carryOut = refs => {
let fn = item => subsidiary.observe(item.$el || item);
let arrFn = () => refs && refs.map(item => subsidiary.observe(item.$el || item));
switch (dataType(refs)) {
case "HTMLImageElement": fn(refs); break; // 监听一个dom
case "HTMLDivElement": fn(refs); break; // 监听一个dom
case "Array": arrFn(refs); break; // 监听多个dom
default: return false;
};
};
// console.log(carryOut,'carryOut')
return carryOut;
};
// 让元素到达指定位置
export function Scroll(dom = '', config = {}) {
let configs = { behavior: "smooth", block: "start", ...config };
dom && dom.scrollIntoView && dom.scrollIntoView(configs);
};
test.vue文件
<template>
<div class="box">
<ul>
{{ active }}==active
<li
class="li"
v-for="(item,index) in arr"
@click="changeNav(item.id)"
:class="active == item.id ? 'active' : ''"
:key="index"
>第{{item.name}}导航</li>
</ul>
<div>
<div class="div" ref="SCROLL" v-for="(item,index) in arr" :key="index + 'a'">第{{item.name}}内容</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
active: 0,
arr: [
{ id: 0, name: 0 },
{ id: 1, name: 1 },
{ id: 2, name: 2 },
{ id: 3, name: 3 },
{ id: 4, name: 4 },
{ id: 5, name: 5 }
],
subsidiary: this.$FN.elVisible(this.fn)
};
},
mounted() {
this.$nextTick(() => {
window.addEventListener("scroll", this.findNav);
});
},
methods: {
findNav() {
this.getRef();
},
getRef() {
let refs = this.$refs.SCROLL;
this.subsidiary(refs);
},
fn(res) {
let index = res.innerText[1];
console.log( res.innerText,' res.innerText',index,'index')
this.active = index;
},
changeNav(i) {
this.active = i;
this.$FN.Scroll(this.$refs.SCROLL[i]);
}
}
};
</script>
<style lang="less" scoped>
.box {
width: 50%;
display: flex;
margin: auto;
justify-content: space-between;
ul {
position: fixed;
left: 20%;
top: 100px;
.li {
line-height: 30px;
background-color: antiquewhite;
margin-bottom: 20px;
padding: 10px;
}
}
.div {
height: 500px;
background-color: antiquewhite;
margin-bottom: 20px;
width: 500px;
text-align: center;
line-height: 500px;
}
.active {
color: red;
}
}
</style>
main.js文件 引入public/index.js
import * as FN from '@/public';
Vue.prototype.$FN = FN;