Vue侧边索引跳转
效果如图所示:
- 首先要去除不存在的几个首字母(我刚开始没有去除,于是前面是还很正常的跳转,后面就会有偏差,这图看上去点击的和跳转的有偏差,实际上是没有的哈)
- 需要跳转的列表要先排好序
- 要明白侧边的索引和列表的index是一一对应的,所以index是关键
- 获取到索引的index,找到列表对应的index,将列表index的offsetTop赋值给document.documentElement.scrollTop(是试出来的,我的情况是滚动条是给到html、body的,可以先测试获取滚动条在的具体地方,再赋值)
- 侧边的布局就是简单的display:flexed,然后设置top,right
具体代码
先是排序(按照首字母排序)和归类,obj中的index就是首字母,list就是首字母对应index的城市信息数组
isABC(data) {
// objList=[{index:"A",list:[...]},{index:"B",list:[...]},{index:"C",list:[...]}],最后要返回的列表
let objList = [],
l = data.length
//循环判断
for (let i = 0; i < l; i++) {
var firstChar = data[i].pinyin.charAt(0).toUpperCase()
if (isIn(firstChar)) { //如果不存在索引的,则添加进去
objList.push({
index: firstChar,
list: [{
name: data[i].name,
cityId: data[i].cityId
}]
})
} else {
// 已经存在了index,那么就先循环找到那个index,然后在list中推入这个城市的信息
for (let j = 0; j < objList.length; j++) {
if (firstChar === objList[j].index) {
objList[j].list.push({
name: data[i].name,
cityId: data[i].cityId
})
}
}
}
}
// 判断是否存在index的函数
function isIn(firstChar) {
for (let i = 0, l = objList.length; i < l; i++) {
if (firstChar === objList[i].index) { //如果有
return false
}
}
// 没有,第一次比较objList.length=0 ,直接返回true
return true
}
// 返回排序后的数组
return objList.sort((a, b) => {
if(a.index>b.index){
return 1
}else if(a.index<b.index){
return -1
}else{
return 0
}
})
}
组件的模板
<template>
<div id="adds">
<ul id="hot">
<h3>热门城市</h3>
<li v-for="item in hot" :key="item.cityId">
{{item.name}}
</li>
</ul>
<!-- ref方便操作节点-->
<div id="add" ref="inCity">
<!-- 循环每个index-->
<ul v-for="item in posList" :key="item.cityId">
<h2>{{item.index}}</h2>
<!-- 遍历渲染list里的城市-->
<li v-for="city in item.list" :key="city.cityId">
{{city.name}}
</li>
</ul>
</div>
<ul id="index">
<li v-for="(item,index) in indexList" :key="index" @click="change(index)">{{item}}</li>
</ul>
</div>
</template>
逻辑实现
change(index) {
let h2 = this.$refs.inCity.getElementsByTagName('h2')
// 这里我减去100,是因为css中距离顶部有100的padding值
//#adds {padding-top: 100px;height: 200px;}
document.documentElement.scrollTop = h2[index].offsetTop - 100
}