本博客标题指示灯代码



<!--指示灯-->
<script>
    $(function () {
        //当box容器加入到html文档中作为节点
        $("body").prepend(` 
                    <div id="title_box">
                        <div id="content" >
                
                        </div>
                    </div>
            `)
        //var arr = ["h1","h2","h3","h4","h5","h6"]
        var test_box = $("#cnblogs_post_body");     //文章容器
        var test_box_childs = test_box.children();  //文章的子节点
        var pick_title_node = []        //有效的title节点
    
        //每个小盒子的长度
        var box_height = 30                   //mbox容器box的高度
        var bbb = "#9c9c9c"  //最外层容器的背景颜色
        var mbox_width = $(window).width()/5.5         //mbox的宽度
        var mbox_margin_size = 2.5  //margin的外边距大小
        var active_color = "#0681ba"  //mbox活跃时的背景颜色
        var mbox_color = "rgba(85, 85, 85,0.9)" //mbox中的背景颜色
        var color = "#ebebeb"  //mbox中的文字颜色
        var current_index = 0  //现在的mbox_index或当前的标题对应的index
        var listen_scroll = true //是否处理滚动条事件
        var tops_size = [] //各个标题距顶部的高度
        


        //选择出标题有效元素节点
        for (i = 0; i < test_box_childs.length; i++) {
            unit_node = test_box_childs[i];
            if (unit_node.localName.indexOf("h1") == 0 || unit_node.localName.indexOf("h2") == 0  || unit_node.localName.indexOf("h3") == 0) {
                pick_title_node[pick_title_node.length] = unit_node
            }
        }
        //与主题结耦了,判断是用我们的指示灯还是主题的目录
        if(pick_title_node.length > 20 || pick_title_node.length == 0) {
            //相当不用我们的指示灯了
            window.onload = function(){
                document.getElementById('articleDirectory').style="display:block;"
                document.getElementById('home').style="margin-top: 332px;margin-left: 4%;"
            }
            return;
        }
        //将元素节点进行加工成mbox html且追加到页面中作为节点 & 将同将title距顶部的高度加到容器中
        for (i = 0; i < pick_title_node.length; i++) {
            title_str = pick_title_node[i].innerText.trim()
            $("#content").append("<div id='title_index_" + i + "' title='" + title_str + "'>" + title_str + "</div>")
            tops_size[tops_size.length] = $(pick_title_node[i]).offset().top
        }


        //设置整体盒子样式
        if (pick_title_node.length > 0) {
            $("#title_box").css({
                "position": "fixed",
                "left": "0px",
                "right": "0px",
                "top": "0px",
                "font-size": "10px",
                "background": bbb,
                "overflow": "hidden",
                "z-index": "10",
                "border-bottom": "1px solid #bbbbbb"
            })
            $("#content").css({
                "height": box_height + "px",
                "overflow": "hidden",
                "width": mbox_width * pick_title_node.length + mbox_margin_size * 2 * pick_title_node.length + 250 + "px",
                "position": "relative"

            })
            $("#content").children().css({
                "float": "left",
                "width": mbox_width + "px",
                "height": "25px",
                "line-height": "25px",
                "background": mbox_color,
                "margin": mbox_margin_size + "px",
                "padding": "0px 5px",
                "box-sizing": " border-box",
                "overflow": "hidden",
                "text-overflow":"ellipsis",
                "white-space": "nowrap",
                "cursor": "pointer",
                "color": color,
                "font-weight": "700"

            })


        }

        //防抖函数模板
        function debounce(func, delay) {
            let timer = null;
            return function (...args) {
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                    func.apply(this, args)
                }, delay)
            }
        }
        //定位指示灯
        //判断mbox的left是否超出,如果超时调整位置
        function toLamp() {
            //执行体
            console.log("指针灯排校准中~");
            //盒子在盒子父容器中距离左边的大小
            console.log("current_index=",current_index,"总盒子:"+ tops_size.length);
            mbox_position_left = $("#title_index_" + current_index).position().left
            //窗口可见宽度
            window_width = $(window).width();
            console.log(mbox_position_left , window_width);
            if (mbox_position_left > window_width) {
                $("#content").animate({
                    // 将当前盒子向左移
                    "left": -mbox_position_left + mbox_width + box_height + "px"
                })
            } else {
                $("#content").animate({
                    "left": "0px"
                })
            }

        }
        //创建刷新指示灯的防抖函数
        const refresh = debounce(toLamp, 80)

        //有动画地滚动
        function ScrollTo(scroll,top) {
            let st = setInterval(function() {
                let currentTop = $(scroll).scrollTop();
                let currentTo = 0;
                //每次移动的跨度
                let span = 40;
                //当在跨度内时,直接到达
                if(currentTop >= top - span && currentTop <= top + span) {
                    $(scroll).scrollTop(top);
                    clearInterval(st);
                    return;
                }
                //如果不在跨度内时,根据当前的位置与目的位置进行上下移动指定跨度
                if(currentTop < top) {
                     $(scroll).scrollTop(currentTop+span)
                }else {
                    $(scroll).scrollTop(currentTop-span)
                }
            },10)
        }
        //当点击mbox时进行事件委托
        $("#content").on("click", "div", function () {
            //点击的index
            index = parseInt($(this).prop("id").split("_")[2])
            //text中真实的obj
            node = pick_title_node[index]
            //所在位置
            mbox_top = $(node).offset().top
            //定位到该元素的位置
            ScrollTo(window,mbox_top - box_height)
            

            //维护指示灯
            $("#title_index_" + index).css({
                "background": active_color
            }).siblings().css({
                "background": mbox_color
            })
            //调整活跃的mbox到可视位置1
            refresh()
            //维护index
            current_index = index

        });

        //监听窗口滑动
        $(window).scroll(function () {
            //查看是否要监听scroll
            if (listen_scroll) {
                //维护tile高度容器
                for (h = 0; h < pick_title_node.length; h++) {
                    tops_size[h] = $(pick_title_node[h]).offset().top
                }
                //当前可视窗口距顶部的位置
                let current_top = this.scrollY + box_height;
                //判断在哪个title内 (中间拖动值)
                let hide_height = current_top + box_height; //与 tops_size 结合判断,得出 current_index
                //维护全局变量 current_index
                if(current_top <= tops_size[0]) {//判断是否是第一个
                    current_index = 0;
                }else if(current_top >= tops_size[tops_size.length-1] - 10) { //看是否是最后一个, 减10是解决未知的bug
                    current_index = tops_size.length-1;
                }else { //根据当前位置与标题的top得到, 与平常的数组遍历不同,这里是 tops_size.length-1
                    for (j = 0; j < tops_size.length-1; j++) { 
                        if(hide_height >= tops_size[j]   && hide_height < tops_size[j+1]) {
                            current_index = j;
                        }                    
                    }
                }
                //去更新
                $("#title_index_" + current_index).css({
                        "background": active_color
                    }).siblings().css({
                        "background": mbox_color
                })
                //调整活跃的mbox到可视位置2
                refresh()
                
            }
            



        })


    })
</script>




 

 

 
posted @ 2021-11-06 11:52  小庄的blog  阅读(46)  评论(0编辑  收藏  举报