美文网首页
关于侧边栏滚动导航事件

关于侧边栏滚动导航事件

作者: 王二麻子88 | 来源:发表于2020-12-04 11:07 被阅读0次

    侧边栏滚动导航事件

    // TODO
    
    $(function() {
        var ctrl = {
            scrollHandler: function() {
                var self = this;
                var win = $(window);
                var docs = $('.docs');
                var navContainer = $('#J-nav');
                var navItem = $('.nav-section-item');
                // heaerHeight 除外其他的干扰因素, outerHeight属性是计算包含内外边距在内的高度
                var headerHeight = $('.documentation').outerHeight() + $('.topbar').outerHeight();
    
                // 设置位置参数列表, 包含每个锚点距离正文顶部的高度
                var positions = [];
                // h3是标记标签
                $('h3', docs).each(function() {
                    var current = $(this);
                    var text = current.text();
                    var anchor = text.split(' ')[0];
    
                    positions.push(parseInt(current.offset().top));  // 获取每个锚点距离正文的高度
                    navItem.filter('[href="#'+ anchor +'"]').attr('rel', positions.length - 1);
    
                });
    
                var positionLength = positions.length;
                // 设置防抖节点, 在一定时间内滚动不做处理
                var timer;
    
                // 监听window的滚动事件
                win.scroll(function() {
                    // 获取正文被卷去的高度
                    var scrollTop = win.scrollTop();
    
                    navContainer.css('top', scrollTop >= headerHeight ? 0 : Math.min(headerHeight, headerHeight - scrollTop));
                    // 防止重复设置侧边整体的位置
                    if (self.noscroll) {
                        self.noscroll = false;
                        return;
                    }
    
                    // 延迟函数是防抖的写法, 延迟函数内部才是主要内容
                    if (timer) clearTimeout(timer);
                    timer = setTimeout(function() {
                        for (var i = 0; i < positionLength; i++) {
                            if (scrollTop < positions[0]) {
                                self.backNav();
                                return;
                            }
    
                            if ( (positions[i] <= scrollTop) && (positions[i + 1] > scrollTop) ) {
                                self.selectNav(i);
                            }
                        }
                    }, 50);
                });
    
                // 主动触发某个事件
                win.trigger('scroll');
            },
    
            // 设置观察者事件==> 监听各种点击事件
            observer: function() {
                var self = this;
    
                self.addAnchors();  // 添加
                self.addNav();  // 生成侧边的导航栏
    
                var navItem = $('.nav-section-item');
                var navTitle = $('.nav-section-title');
                var gotoTop = $('#gototop');
    
                // 点击侧边子标题事件
                navItem.on('click', function() {
                    var current = $(this);
                    var index = current.attr('rel');
    
                    navItem.removeClass('active');
                    current.addClass('active');
    
                    self.selectNav(index);
                });
    
                // 点击侧边栏主标题事件
                navTitle.on('click', function() {
                    var current = $(this);
                    self.selectNav(current.next().attr('rel'));
                    self.noscroll = true;
                });
    
                // 返回顶部事件
                gotoTop.on('click', function() {
                    $('body').get(0).scrollTop = 0;
                });
    
                // 注册滚动监听事件
                self.scrollHandler();
    
            },
    
            // add anchors 生成正文的锚点标签
            addAnchors: function() {
                var docs = $('.docs');
    
                $('h3', docs).each(function() {
                    var current = $(this);
                    var anchor = current.text().split(' ')[0];
    
                    current.before('<a name="'+ anchor +'"></a>');
                });
            },
    
            // add nav
            addNav: function() {
                var docs = $('.docs');
                var navContainer = $('#J-nav');
                var newNav = '';
    
                var hash = (function() {
                    var result = {};
                    var currentItem;
    
                    $('h1, h2, h3', docs).each(function() {
                        var current = $(this);
                        var tagName = this.tagName.toLowerCase();  // 标签转小写
                        var text = current.text();
                        var anchor = text.split(' ')[0];
    
                        if (tagName === 'h1') {
                            if (text !== 'Constructor' && text !== 'Configuring Defaults') {
                                currentItem = result[text] = result[text] || [];
                                current.before('<a name="'+ text.replace(' ', '') +'"></a>');
                            }
                        }
                        else if (tagName === 'h2') {
                            currentItem = result[text] = result[text] || [];
                            current.before('<a name="'+ text.replace(' ', '') +'"></a>');
                        }
                        else if (tagName === 'h3') {
                            currentItem.push(anchor);
                        }
                    });
    
                    return result;
                })();
    
                for (var cat in hash) {
                    if (hash.hasOwnProperty(cat)) {
                        newNav += '<div class="nav-section">';
                        newNav += '<div class="nav-section-title"><a href="#'+ cat.replace(' ', '') +'">'+ cat +'<\/a><\/div>';
    
                        $.each(hash[cat], function(index, name) {
                            newNav += '<a class="nav-section-item" href="#'+ name +'">'+ name +'<\/a>';
                        });
    
                        newNav += '<\/div>';
                    }
                }
    
                navContainer.html(newNav);
            },
    
            // select nav
            selectNav: function(index) {
                var navContainer = $('#J-nav');
                var navItem = $('.nav-section-item', navContainer);
    
                navItem.eq(navContainer.data('menuon')).removeClass('active').parent().removeClass('active');
                navItem.eq(index).addClass('active').parent().addClass('active');
                navContainer.data('menuon', index);
            },
    
            // nav init
            backNav: function() {
                var navContainer = $('#J-nav');
                var navSection = $('.nav-section', navContainer);
                var navItem = $('.nav-section-item', navContainer);
    
                navSection.removeClass('active');
                navItem.removeClass('active');
    
                navSection.eq(0).addClass('active');
    
                navContainer.data('menuon', 0);
            },
    
            // 插入 皮肤事件
            insertSkin: function() {
                var skindemo = $('#J-skin-demo');  //  这是一个用 display: none 制作的模板
                var h1 = $('h1');
    
                h1.each(function() {
                    var current = $(this);
    
                    if (current.text() === 'Skin') {
                        // 标记物后面插入模板
                        current.next().after(skindemo);
                        // 将模板显示出来
                        skindemo.removeAttr('style');
                    }
                });
            },
    
            prettyprint: function() {
                $('pre').addClass('prettyprint linenums');
    
                window.prettyPrint && prettyPrint();
            },
    
            // 初始化标签
            init: function() {
                ctrl.observer();
                ctrl.prettyprint();
                ctrl.insertSkin();
            }
        };
    
        ctrl.init();
    });
    

    html部分:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <div class="docs">
            <div class="nav" id="J-nav">
                <div class="nav-section active">
                    <div class="nav-section-title">Attributes</div>
                    <a class="nav-section-item active" href="#header">header</a>
                    <a class="nav-section-item" href="#footer">footer</a>
                    <a class="nav-section-item" href="#dataSource">dataSource</a>
                    <a class="nav-section-item" href="#locator">locator</a>
                </div>
                <div class="nav-section">
                    <div class="nav-section-title">Methods</div>
                    <a class="nav-section-item">previous</a>
                    <a class="nav-section-item">next</a>
                </div>
            </div>
            <div class="content">
                <!-- h1 算是一整页的内容 -->
                <h1>Constructor</h1>
                <!-- h2 是一级标题 -->
                <a name="Commonlyused"></a>
                <h2>Commonly used</h2>
                <!-- h3 是二级标题 -->
                <a name="dataSource"></a>
                <h3>dataSource <em>array | string | object | function</em></h3>
            </div>
        </div>
        <!-- 返回顶部的图标 -->
        <div id="gototop">Top</div>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:关于侧边栏滚动导航事件

          本文链接:https://www.haomeiwen.com/subject/ywibwktx.html