需求分析
思路分析
- 先做佈局
- 通過監聽右側導航的滑動或點擊,獲取當前Y軸位置,賦予列表相同的位置,實現列表的滾動
- 列表的滾動,獲取位置範圍,完成右側導航定位
一,頁面佈局
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,user-scalable=no" />
<meta charset="UTF-8">
<title>城市列表</title>
<style type="text/css">
ul {
margin: 0;
padding: 0;
list-style: none;
}
.list-wrapper{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
background: #fff;
}
.index-list-content{
background: #fff;
border-radius: 2px;
}
.index-list-title{
padding: 14px 16px;
font-size: 14px;
line-height: 1.6;
color: #333;
}
.index-list-anchor{
padding: 16px 16px 10px 16px;
line-height: 1;
font-size: 14px;
color: #999;
background: #f7f7f7;
}
.index-list-item {
position: relative;
height: 50px;
line-height: 50px;
padding: 0 16px;
font-size: 14px;
color: #333;
}
.index-list-item:last-child{
border: none;
}
.index-list-item_active{
background: #ddd;
}
.index-list-fixed{
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
padding: 16px 16px 10px 16px;
box-sizing: border-box;
font-size: 14px;
line-height: 1;
color: #999;
background: #f7f7f7;
}
.index-list-nav {
position: absolute;
z-index: 30;
right: 0;
top: 50%;
transform: translateY(-50%);
font-family: Helvetica;
}
.index-list-nav ul {
padding: 0;
margin: 0;
}
.index-list-nav li{
padding: 6px 16px 0 16px;
line-height: 1;
text-align: center;
box-sizing: border-box;
font-size: 12px;
color: gray;
}
.index-list-nav .active {
color: blue;
}
</style>
</head>
<body>
<div class="list-wrapper">
<div class="scroll-content">
<div class="index-list-content">
<div class="index-list-title">
定位城市:
</div>
<ul>
<li>
<h2 class="index-list-anchor">
★熱門城市
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
北京市
</li>
<li class="index-list-item border-bottom-1px">
上海市
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
A
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
鞍山市
</li>
<li class="index-list-item border-bottom-1px">
安慶市
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
B
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
北京市
</li>
<li class="index-list-item border-bottom-1px">
巴音郭楞州
</li>
<li class="index-list-item border-bottom-1px">
博爾塔拉州
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
C
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
成都市
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
E
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
鄂爾多斯市
</li>
<li class="index-list-item border-bottom-1px">
鄂州市
</li>
<li class="index-list-item border-bottom-1px">
恩施州
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
F
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
福州市
</li>
<li class="index-list-item border-bottom-1px">
佛山市
</li>
<li class="index-list-item border-bottom-1px">
防城港市
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
G
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
廣州市
</li>
<li class="index-list-item border-bottom-1px">
貴陽市
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
H
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
杭州市
</li>
<li class="index-list-item border-bottom-1px">
和田地區
</li>
</ul>
</li>
<li>
<h2 class="index-list-anchor">
Z
</h2>
<ul>
<li class="index-list-item border-bottom-1px">
鄭州市
</li>
<li class="index-list-item border-bottom-1px">
張家口市
</li>
<li class="index-list-item border-bottom-1px">
張家界市
</li>
<li class="index-list-item border-bottom-1px">
珠海市
</li>
<li class="index-list-item border-bottom-1px">
中山市
</li>
<li class="index-list-item border-bottom-1px">
自貢市
</li>
<li class="index-list-item border-bottom-1px">
資陽市
</li>
<li class="index-list-item border-bottom-1px">
棗莊市
</li>
<li class="index-list-item border-bottom-1px">
舟山
</li>
<li class="index-list-item border-bottom-1px">
遵義市
</li>
<li class="index-list-item border-bottom-1px">
淄博市
</li>
<li class="index-list-item border-bottom-1px">
株洲市
</li>
<li class="index-list-item border-bottom-1px">
中衛市
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="index-list-nav">
<ul>
<li data-index="0" class="active">
★
</li>
<li data-index="1">
A
</li>
<li data-index="2" class="">
B
</li>
<li data-index="3" class="">
C
</li>
<li data-index="4" class="">
E
</li>
<li data-index="5" class="">
F
</li>
<li data-index="6" class="">
G
</li>
<li data-index="7" class="">
H
</li>
<li data-index="8" class="">
Z
</li>
</ul>
</div>
<div class="index-list-fixed" style="display: none;">
A
</div>
<script type="text/javascript" src="./bscroll.js"></script>
<script type="text/javascript" src="./city.js"></script>
</body>
</html>
由於js較大,分離開了
二,初始化(city.js)
- 封裝匿名自執行函數
- 獲取各個需要操作的元素
- 初始化
(function(){
//獲取外框
var list = document.querySelector(".list-wrapper");
//獲取導航的ul
var indexListNav = document.querySelector(".index-list-nav");
//後面的步驟 setNav之後
var indexListNavs = indexListNav.querySelectorAll("li");
//獲取頂部索引
var indexListFixed = document.querySelector(".index-list-fixed");
//nav獲取之後操作 return index之後
var indexListContent = document.querySelector(".index-list-content");
//獲取ul下所有li
var indexLists = indexListContent.children[1].children;
//初始化
var indexList = new BScroll(list,{
//事件派發
probeType:3
})
})();
三,監聽右側列表的滑動或者點擊,獲取位置
爲了方便大家理解,我的調試步驟也在
indexListNav.addEventListener("touchstart",(e)=>{
//可以獲取到dom節點
// console.log(e.target);
//Y軸位置 座標
// console.log(e.changedTouches[0].clientY);
setIndex(e.changedTouches[0].clientY);
})
indexListNav.addEventListener("touchmove",(e)=>{
// console.log(e.changedTouches[0].clientY);
//可以獲取到dom節點
setIndex(e.changedTouches[0].clientY);
})
//設置座標
function setIndex(y){
let index = getIndex(y);
if(index < 0 || index >9){
//沒有對應元素
return;
}
//滾動到對應元素上去 li 過渡時間
indexList.scrollToElement(indexLists[index],100);
}
//拿到座標
function getIndex(y){
//第二步 獲取它相對於可視區的距離
var navTop = indexListNav.getBoundingClientRect().top;
var h = 18; //nav li的高
//計算一下 得到index
// var index = y/18; 下方轉換
// 轉換成相對於nav的距離
var index = parseInt((y-navTop)/18); //0-8
//打印出來看一下
// console.log(index);
return index;
}
第一二步完美實現
第三步
定義一個設置右側導航active的方法
//nav active 控制
function setNav(index){
//先獲取所有的a標籤
indexListNavs.forEach((li)=>{
li.classList.remove("active");
})
//效果演示
indexListNavs[index].classList.add("active");
}
監聽列表滾動事件,導航定位進行對應改變
indexList.on("scroll",(e)=>{
//拿到y軸 做一個比較
var y = -e.y;
//是個負值 爲了方便計算 轉一下 我們要獲取top值
//排除定位城市:背景這一行 第0項 未超過第一項就不顯示頂部
if(y < indexLists[0].offsetTop){
setNav(0);
//最後一步 第0項不需要顯示
indexListFixed.style.display = "none";
//演示 清掉所有的
return;
}
//過了第[0]項 實際爲第一項 顯示它
indexListFixed.style.display = "block";
//到倒數第二項
//循環indexLists 下面每個li
//最後一個單獨處理 因爲最後一項i+1這個表達式就不成立了
for(var i = 0; i < indexLists.length - 1; i++){
//滾動距離是否大於當前項,並且小於下一項,是的話,就說明還在當前項
if(y >= indexLists[i].offsetTop &&
y < indexLists[i+1].offsetTop){
setNav(i);
//最後一步 給個值
indexListFixed.innerHTML = indexLists[i].children[0].innerHTML;
return;
}
}
setNav(indexLists.length - 1);
//最後一項設置
indexListFixed.innerHTML = indexLists[indexLists.length - 1].children[0].innerHTML;
})
大功告成,完結撒花
此篇博客爲本人原創
轉載請註明出處