zoukankan      html  css  js  c++  java
  • 案例:电梯导航功能

    实现功能:

    1. 点击左边的小li,会滚动到右边对应的内容区(电梯导航 -> 内容区)

    ① 当滚动到某一位置时,就让电梯导航显示出来

    ② 点击电梯导航页面可以滚动到相应内容区域

    ③ 核心算法:因为电梯导航模块和内容区模块是一一对应的,所以对应的索引号是一样的

    ④ 当点击电梯导航某个小模块时,就可以拿到当前小模块的索引号

    ⑤ 就可以把animate要移动的距离求出来:当前索引号内容区模块它的offset().top

    ⑥ 然后执行动画即可

    2. 当滚动到右边的内容区,作边的小li会添加相应的类(内容区 -> 电梯导航)

    ① 当点击电梯导航的某个小li,当前小li添加current类,兄弟移除类名

    ② 当页面滚动到内容区域某个模块,左侧电梯导航相对应的小li模块,也会添加current类,兄弟移除current类

    ③ 触发的事件是页面滚动,因此这个功能要写到页面滚动事件里面

    ④ 需要用到each遍历内容区域大模块。each里面能拿到内容区域每一个模块元素和索引号

    ⑤ 判断的条件:被卷去的头部 >= 内容区域里面每个模块的offset().top

    ⑥ 就利用这个索引号找到相应的电梯导航小li,添加current类

    一个bug:当我们刷新页面的时候并不能显示电梯导航,这是因为我们写的代码只允许页面滚动的时候,并且滚动到一定的位置才能显示电梯导航

    解决办法:将显示和隐藏电梯导航的功能封装到一个函数里去,在页面加载的时候调用一次,页面滚动的时候再调用一次

    另一个bug:此时如果点击电梯导航的某一个小li时,会出现重新把其他的小li样式背景选择一遍之后才到被点击的小li上。而我们想要的效果是,点击某个小li后,直接去往被点击的小li那添加样式,而不需要它多次选择其他的小li,出现类似抖动的情况

    为什么会出现这个问题呢?这是因为我们的代码中写的是,当我们点击某个小li之后,会使我们的页面滚动起来,而在滚动的过程中,会触发给当前内容区对应的小li增加样式的事件。

    如何解决呢?当我们点击了小li,此时不需要执行页面滚动事件里面的小 li 的背景选择。

    我们可以使用节流阀的方法,也叫互斥锁,增加一个flag判断条件,判断是点击事件还是滚动事件,如果是点击事件,就上一个锁,不要执行滚动事件里面的代码,点击事件完成之后再释放锁。

        <!-- 楼层区 start -->
        <div class="floor">
            <!-- floor不需要给高度,里面的楼层盒子撑开就行了 -->
            <!-- 一楼家电模块 -->
            <div class="jiadian w">
                家用电器模块
            </div>
            <!-- 二楼手机模块 -->
            <div class="shouji w">
                手机通讯模块
            </div>
            <!-- 三楼电脑模块 -->
            <div class="diannao w">
                电脑办公模块
            </div>
            <!-- 四楼家具模块 -->
            <div class="jiaju w">
                精品家具模块
            <!-- 之后的楼层都接在后面叠加,布局直接采用上面的样式布局,不需要做大的修改 -->
        </div>
        <!-- 楼层区 end -->
    
        <!-- 固定电梯导航 start -->
        <div class="fixedtool">
            <ul>
                <li class="current">家用电器</li>
                <li>手机通讯</li>
                <li>电脑办公</li>
                <li>家具家居</li>
            </ul>
        </div>
        <!-- 固定电梯导航 end -->
    // JS逻辑代码
    $(function() {
        // 当我们点击了小li,此时不需要执行页面滚动事件里面的小 li 的背景选择。
        // 使用节流阀的方法,设置一个flag标识
        var flag = true;
        // 1. 显示隐藏电梯导航
        // 直到滚动条滚动到今日推荐的部分,就显示电梯导航
        var toolTop = $(".recommend").offset().top;
        toggleTool();
        // 显示和隐藏电梯导航的功能,在页面加载的时候调用一次
        function toggleTool() {
            if ($(document).scrollTop() >= toolTop) {
                $(".fixedtool").fadeIn();
            } else {
                $(".fixedtool").fadeOut();
            }
        }
        // 在页面滚动的时候再调用一次
        $(window).scroll(function() {
            toggleTool();
            // 3. 页面滚动到某个内容区域,左侧电梯导航小li相应添加和删除current类名
            if (flag) {
                $(".floor .w").each(function(i, ele) {
                    if ($(document).scrollTop() >= $(ele).offset().top) {
                        // console.log(i);  i表示当前内容区的索引号
                        $('.fixedtool li').eq(i).addClass('current').siblings().removeClass('current');
                    }
                });
            }        
        });
        // 2. 点击电梯导航页面可以滚动到相应的内容区域
        $('.fixedtool li').click(function() {
            flag = false;
            // console.log($(this).index());
            // 点击之后让当前的小li添加背景颜色,兄弟元素清除样式
            $(this).addClass('current');
            $(this).siblings().removeClass('current');
            // 当每次点击小li,就需要计算出页面要去往的位置
            // 选出对应索引号的内容区的盒子,计算它的.offset().top
            var current = $(".floor .w").eq($(this).index()).offset().top;
            // 页面动画滚动效果
            $("body, html").stop().animate({
                scrollTop: current
            }, function() {
                // 当点击小li,执行页面滚动动画完成之后,打开节流阀
                flag = true;
            });
        });
    })
  • 相关阅读:
    洛谷P1613 跑路
    洛谷P2149 Elaxia的路线
    洛谷P3119 草鉴定
    洛谷P1972 HH的项链
    洛谷P2458 保安站岗
    uva10061
    uva579
    uva 127 "Accordian" Patience
    uva10177 (2/3/4)-D Sqr/Rects/Cubes/Boxes?
    uva156
  • 原文地址:https://www.cnblogs.com/zcy9838/p/13022453.html
Copyright © 2011-2022 走看看