移动端滚动神器 better-scroll 系列篇四 原生js+BS 实现 城市列表,锚点定位

简介: 笔记

需求分析



4.png


思路分析



  1. 先做布局
  2. 通过监听右侧导航的滑动或点击,获取当前Y轴位置,赋予列表相同的位置,实现列表的滚动
  3. 列表的滚动,获取位置范围,完成右侧导航定位



一,页面布局


<!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)


  1. 封装匿名自执行函数
  2. 获取各个需要操作的元素
  3. 初始化
(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;
    })

大功告成,完结撒花


目录
相关文章
|
11天前
|
移动开发 前端开发 JavaScript
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
本文介绍了一个使用JavaScript和HTML5 Canvas API实现的贪吃蛇游戏的升级版本,该版本支持PC端和移动端,提供了丝滑的转向效果,并允许玩家通过键盘或触摸屏控制蛇的移动。代码中包含了详细的注释,解释了游戏逻辑、食物生成、得分机制以及如何响应不同的输入设备。
27 1
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
|
7天前
|
JavaScript 前端开发 索引
JavaScript HTML DOM 节点列表
JavaScript HTML DOM 节点列表
12 5
|
11天前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
13 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
2月前
|
JavaScript 数据可视化
JS如何优雅的实现模块自动滚动展示
【8月更文挑战第22天】JS如何优雅的实现模块自动滚动展示
20 1
JS如何优雅的实现模块自动滚动展示
|
25天前
|
JavaScript 前端开发
js怎么定位不同的页面元素
在JavaScript中,有多种方法定位和选择页面元素。
|
2月前
|
Devops 持续交付 测试技术
JSF遇上DevOps:开发流程将迎巨变?一篇文章带你领略高效协同的魅力!
【8月更文挑战第31天】本文探讨了如何在JavaServer Faces(JSF)开发中融入DevOps文化,通过持续集成与部署、自动化测试、监控与日志记录及反馈机制,提升软件交付速度与质量。文中详细介绍了使用Jenkins进行自动化部署、JUnit与Selenium进行自动化测试、ELK Stack进行日志监控的具体方法,并强调了持续改进的重要性。
31 0
|
2月前
|
JavaScript 前端开发 API
从零开始学表单操作,jQuery 与原生 JavaScript 完全指南,带你轻松掌握网页交互关键!
【8月更文挑战第31天】在网页开发中,表单是实现用户互动的关键元素。无论是收集信息、提交数据还是验证输入,都需要对表单进行有效操作。本文档介绍了如何使用原生 JavaScript 和 jQuery 操作表单,包括获取表单元素、读写表单值、处理表单提交及验证等核心功能。jQuery 提供了更简洁的语法和更好的兼容性,但原生 JavaScript 在性能上有优势。选择合适的方法取决于项目需求和个人偏好。下面通过具体示例展示了两种方式的操作方法。
22 0
|
2月前
|
JavaScript 前端开发
使用js,html,css实现歌词滚动的效果
使用js,html,css实现歌词滚动的效果
44 0
|
3月前
|
JavaScript
【vue】 vue2 | js 实现数字滚动效果
【vue】 vue2 | js 实现数字滚动效果
52 0
|
3月前
|
JavaScript
js 滚动鼠标滑轮放大缩小图片
js 滚动鼠标滑轮放大缩小图片
22 0