写个这小玩意真麻烦
html
<template>
<div id="retrieve-components">
<el-input v-model="searchVal" @input="search" placeholder="请输入" class="mb-10"></el-input>
<div class="box flex" id="box">
<div class="letter">
<div v-for="(item, index) in letter" :key="index" class="mb-2 item" :class="[{active:selectItem == item}]" :id="`left-key-${item}`" @click="retrieveClick(item)">
{{ item }}
</div>
</div>
<div class="data-right-box" ref="scrollContainer" @scroll="handleScroll">
<div v-for="(item, index) in peoArray" :key="index" @click="onSelect(item, index)">
<p class="data-key" :id="`right-key-${item.key}`">{{ item.key }}</p>
<p class="data-list" v-for="(ele, e) in item.list" :key="e">{{ ele.name }}</p>
</div>
</div>
</div>
<el-tree :data="peoArray" :props="defaultProps" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }">{{ node.label }}</span>
</el-tree>
</div>
</template>
<script>
export default {
data() {
return {
selectItem: "A",
letter: [],
defaultProps: {
children: 'list',
label: 'name'
},
peoArray: [
{key: "A", list: [{name: "安吉"}, {name: "安吉"}]},
{key: "B", list: [{name: "bar饿啊额日"}, {name: "芭比"}]},
{key: "C", list: [{name: "啛啛喳喳"}, {name: "吃炒菜"}]},
{key: "D", list: [{name: "滴滴滴"}]},
{key: "E", list: [{name: "鹅鹅鹅"}]},
{key: "F", list: [{name: "方慧"}]},
{key: "G", list: [{name: "哥哥"}]},
{key: "H", list: [{name: "话说"}]},
{key: "I", list: [{name: "ID额我热饭v"}]},
{key: "J", list: [{name: "接化发"}]},
{key: "K", list: [{name: "KFC"}]},
{key: "L", list: [{name: "吕布"}]},
{key: "M", list: [{name: "没读书"}]},
{key: "N", list: [{name: "牛头人"}]},
{key: "O", list: [{name: "O泡果奶"}]},
{key: "P", list: [{name: "判断得我"}]},
{key: "Q", list: [{name: "秦三儿"}]},
{key: "R", list: [{name: "如果更方便"}]},
{key: "S", list: [{name: "塞班"}]},
{key: "T", list: [{name: "糖糖"}]},
{key: "U", list: [{name: "U哈哈哈哈"}]},
{key: "V", list: [{name: "V ME 50"}]},
{key: "W", list: [{name: "王富贵"}]},
{key: "X", list: [{name: "喜羊羊"}]},
{key: "Y", list: [{name: "阳顶天"}]},
{key: "Z", list: [{name: "自发热"}]}
],
leftClickFlag: false,
searchVal: "",
};
},
computed: {},
mounted() {
this.letter = Array.from({length: 26}, (_, i) => String.fromCharCode(65 + i));
// this.$refs.scrollContainer.addEventListener('scroll', this.debounce(this.handleScroll, 200));
},
methods: {
search() {
},
handleScroll(event) {
let timeout;
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
timeout = setTimeout(() => {
// this.leftClickFlag = false;
const container = document.querySelector('#box');
const closestElement = this.getClosestElementToTop(container);
this.selectItem = closestElement;
// if (!this.leftClickFlag) {
this.scrollOn(`left-key-${closestElement}`);
// }
}, 500);
},
debounce(func, wait) {
let timeout;
return function (...args) {
const later = () => {
clearTimeout(timeout);
func.apply(this, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
},
getClosestElementToTop(container) {
const elements = document.querySelectorAll(".data-key");
// console.log("container.getBoundingClientRect().top", container.getBoundingClientRect().top);
let closestElement = null;
let closestDistance = Infinity;
for (let element of elements) {
const rect = element.getBoundingClientRect();
const distance = Math.abs(rect.top - container.getBoundingClientRect().top);
// console.log("rect.top", rect.top, distance, distance < closestDistance);
if (distance < closestDistance) {
closestDistance = distance;
closestElement = element;
}
}
return closestElement.innerText;
},
retrieveClick(item) {
this.leftClickFlag = true;
this.selectItem = item;
this.scrollOn(`right-key-${item}`);
},
scrollOn(item) {
let target = document.getElementById(item);
if (target) {
target.scrollIntoView({behavior: "smooth" /*smooth || auto*/});
}
},
// 点击通讯录
onSelect(item, index) {
console.log(item, index);
}
},
beforeDestroy() {
// this.$refs.scrollContainer.removeEventListener('scroll', this.debounce(this.handleScroll, 200));
}
};
</script>
<style lang="scss" scoped>
#retrieve-components {
padding: 10px;
width: 400px;
height: 200px;
background: #fff;
.box {
height: calc(100% - 42px);
.letter {
font-size: 12px;
margin-right: 20px;
justify-content: space-between;
overflow-y: auto;
.item {
padding: 1px;
cursor: pointer;
text-align: center;
&.active {
background: pink;
}
}
}
.data-right-box {
height: 100%;
overflow-y: auto;
flex: 1;
width: 100%;
padding: 0 10px;
.data-key {
margin: 10px 0;
font-size: 12px;
background-color: #f3efef;
}
.data-list {
margin: 20px 0;
}
}
}
}
</style>