目录
监听滚动
<template>
<div class="dataConfirm-create">
<mds-loading :isLoading="detailLoading" type="ball-pulse" loadingText="正在努力加载中" />
<div class="left-wrap">
<!-- 配置模块 -->
<mds-form-item class="mds-form-item-flex" label="配置模块" prop="moduleDataType">
<mds-checkbox-group v-model="formData.moduleDataType">
<mds-checkbox :disabled="showDetail" :value=2>任务确认配置</mds-checkbox>
<mds-checkbox :disabled="showDetail" :value=1>业绩确认配置</mds-checkbox>
<mds-checkbox :disabled="showDetail" :value=3>其他数据确认配置</mds-checkbox>
</mds-checkbox-group>
</mds-form-item>
<div v-show="formData.moduleDataType.includes(2)" class="module-title" id="nav2">任务确认配置</div>
<formComp v-if="formData.moduleDataType.includes(2)" :disabled="showDetail" ref="taskContent" />
<div v-show="formData.moduleDataType.includes(1)" class="module-title" id="nav1">业绩确认配置</div>
<formComp v-if="formData.moduleDataType.includes(1)" :disabled="showDetail" ref="scoreContent" />
<div v-show="formData.moduleDataType.includes(3)" class="module-title" id="nav3">其他数据确认配置</div>
<formComp v-if="formData.moduleDataType.includes(3)" :disabled="showDetail" ref="otherContent" />
<mds-form-item class="bottom-wrap" label-width="0">
<mds-button v-if="!showDetail" size="small" type="primary" @click="submit">保存</mds-button>
<mds-button size="small" @click="cancel">取消</mds-button>
</mds-form-item>
</mds-form>
</div>
</div>
<div class="right-wrap">
<a :class="{ 'is-active': active == 'nav0' }" @click="scroll('nav0', $event)">基本信息</a>
<a v-show="formData.moduleDataType.includes(2)" :class="{ 'is-active': active === 'nav2' }"
@click="scroll('nav2', $event)">任务确认配置</a>
<a v-show="formData.moduleDataType.includes(1)" :class="{ 'is-active': active === 'nav1' }"
@click="scroll('nav1', $event)">业绩确认配置</a>
<a v-show="formData.moduleDataType.includes(3)" :class="{ 'is-active': active === 'nav3' }"
@click="scroll('nav3', $event)">其他数据确认配置</a>
</div>
</div>
</template>
active:string = 'nav0'
moduleNames: { name: string; val: string }[] =[
{ name: '基本信息', val: 'nav0' },
{ name: '任务确认配置', val: 'nav2' },
{ name: '业绩确认配置', val: 'nav1' },
{ name: '其他数据确认配置', val: 'nav3' }
]
.right-wrap {
height: 100%;
width: 200px;
padding-top: 40px;
padding-right: 40px;
margin-left: auto;
a {
line-height: 40px;
color: #5A5F68;
display: block;
padding: 0 22px;
&:hover {
color: #1f6dea;
}
&.is-active {
box-shadow: inset 2px 0px #0364ff;
color: #1f6dea;
}
}
}
隐藏滚动条
.workbench-create {
height: 100%;
display: flex;
.left-wrap {
height: 100%;
overflow: auto;
flex: 1;
padding-left: 40px;
//隐藏元素的滚动条。这通常用于自定义滚动条样式。
scrollbar-width: none;
/* Firefox */
-ms-overflow-style: none;
/* IE 10+ */
&::-webkit-scrollbar {
//伪元素选择器,用于选择Webkit浏览器(如Chrome、Safari等)中的滚动条。
display: none;
/* Chrome Safari */
}
.right-wrap {
height: 100%;
width: 200px;
padding-top: 40px;
padding-right: 40px;
margin-left: auto;
}
}
点击tab锚点
// 锚点
scroll(domId: string, e: any) {
this.isClickScrolling = true;
//延迟设置isClickScrolling,防止与监听滚动冲突
clearTimeout(this.clickScrollTimer);
this.clickScrollTimer = setTimeout(() => {
this.isClickScrolling = false;
}, 102);
// 获取名为 '.right-wrap' 的元素,并将其子元素赋值给变量 'links'
let links: any = document.querySelector('.right-wrap')?.childNodes;
// 遍历 'links' 中的每个元素
links.forEach((element: any) => {
// 如果当前元素拥有类名属性(classList),则移除 'is-active' 类名
element.classList && (element.classList.remove('is-active'));
});
// 给被点击的元素(事件目标 e.target)添加 'is-active' 类名
e.target.classList.add('is-active');
// 根据传入的 'domId' 获取对应的 DOM 元素
const dom = document.querySelector(`#${domId}`);
// 如果找到了该元素,则平滑滚动到该元素所在的视图区域
if (dom) {
dom.scrollIntoView({ behavior: 'smooth' });
}
}
auto: 默认值。滚动行为没有特殊效果,类似于传统的滚动方式,会立即滚动到目标位置。
soomth:在大多数浏览器适用
instant: 滚动到目标位置,但没有平滑效果,瞬间到达。
监听滚动
mounted() {
window.addEventListener('scroll', this.onScroll, true)
}
destroy() {
// 移除滚动事件的监听器,防止内存泄漏
window.removeEventListener('scroll', this.onScroll)
clearTimeout(this.scrollTimer);
clearTimeout(this.clickScrollTimer);
}
onScroll() {
//是点击滚动则不用操作
if (this.isClickScrolling) return;
// 清除之前的定时器
clearTimeout(this.scrollTimer);
//基本上停止滚动后才设置tabs
this.scrollTimer = setTimeout(() => {
const navContents = document.querySelectorAll('.module-title')
const offsetTopArr: any = []
// 存储各个元素相对于顶部的偏移量
navContents.forEach((item: any) => {
//60px>标头48px 留出一定的空间
offsetTopArr.push(item.offsetTop - 60)
})
//获取 '.left-wrap' 元素的滚动距离
const scrollTop = document.querySelector('.left-wrap')?.scrollTop
let navIndex = 0
for (let n = 0; n < offsetTopArr.length; n++) {
if (scrollTop && scrollTop >= offsetTopArr[n]) {
navIndex = n
}
}
this.active = "nav" + navIndex
let links: any = document.querySelector('.right-wrap')?.childNodes;
// 遍历 'links' 中的每个元素
for (let n = 0; n < links.length; n++) {
// 如果当前元素拥有类名属性(classList),则移除 'is-active' 类名
if (links[n].classList && n != navIndex) {
links[n].classList.remove('is-active');
}
};
if (navIndex == 2) navIndex = 1;
else if (navIndex == 1) navIndex = 2;
// console.log("nav" + navIndex);
this.active = "nav" + navIndex
}, 100);
// 时间要比isClickScrolling为true的时间短一点
}