文章页面,左侧滚动内容时右侧目录也在跟着变化
文章页面,左侧滚动内容时右侧目录也在跟着变化的实现(原生的方法jQuery的插件):
先需要引入三个插件库文件:
(1)<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
(2)<script src="jquery.navScrollSpy.js"></script>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * jQuery lightweight plugin boilerplate 3 * @file_name jquery.navScrollSpy.js 4 * @author liuyidi <liuyidi1993@gmail.com> 5 * Licensed under the MIT license 6 * 7 * example: 8 * <ul id="nav"> 9 * <li class="current"><a href="#box1">box1</a></li> 10 * <li><a href="#box2">box2</a></li> 11 * </ul> 12 * $("#nav").navScrollSpy({ 13 * current:"", 14 * scrollSpeed: 750 15 * }); 16 * 滚动监听 点击切换 平滑滚动 17 */ 18 ;(function($, window, document, undefined){ 19 20 //pluginName 21 var pluginName = "navScrollSpy"; 22 //defaults options 23 var defaults = { 24 navContainer: '#nav', //外部容器 25 navItems: 'a', //元素 26 current : 'current', //当前 27 easing : 'swing', //动效 28 speed: 550, //速度 29 // duration: y //方向 30 fixed: true, 31 newTop: "30", //停留在距离顶部的距离 32 oldTop: "180" //最开始的高度 33 }; 34 35 function navScrollSpy(element, options){ 36 this.element = element; //获得id=#nav 37 this.$ele = $(element); //获得$("#nav") 38 this.$win = $(window); //获取window 39 this.options = $.extend({}, defaults, options); //得到参数值 40 41 this._defaults = defaults; 42 this._name = pluginName; 43 44 this.boxs = {}; //定义一个对象用来存放box的top值 45 this.init(); 46 }; 47 48 navScrollSpy.prototype = { 49 init: function(){ 50 //得到a元素 51 this.$a = this.$ele.find(this.options.navItems); 52 //得到内容区Box的top值 53 this.getBoxTop(); 54 55 //点击切换导航按钮样式,更改上下文this 56 this.$a.on("click", $.proxy(this.clickSwitch,this)); 57 58 //滚动切换导航按钮 59 this.$win.on("scroll",$.proxy(this.scrolling,this)); 60 61 //当页面重置时会发生问题? 62 return this; 63 }, 64 65 //导航固定 66 fixNav: function(){ 67 var st = $(window).scrollTop(); 68 var $nav = $(this.options.navContainer) 69 var fixValue = this.options.oldTop; 70 if(st >= fixValue){ 71 $nav.css({ 72 "position":"fixed", 73 "top" : this.options.newTop+"px" 74 }); 75 }else{ 76 $nav.css({ 77 "position":"absolute", 78 "top" : fixValue+"px" 79 }); 80 } 81 }, 82 83 //导航变化 84 changeNav: function(self,$parent){ 85 var current = self.options.current; 86 self.$ele.find("."+current).removeClass(current); 87 $parent.addClass(current); 88 }, 89 90 //得到内容区的Top值 91 getBoxTop: function(){ 92 var self = this; 93 self.$a.each(function(){ 94 var boxId = $(this).attr("href").split('#')[1]; 95 var boxTop = $("#"+boxId).offset().top; 96 //存放boxtop到box对象中去 97 self.boxs[boxId] = parseInt(boxTop); 98 }); 99 }, 100 101 //滚动切换 102 scrolling: function(){ 103 var st = $(window).scrollTop(); 104 var wH = $(window).height(); 105 this.fixNav(); 106 //临界条件: $("#id").offset().top-$(window).scrollTop()>$(window).height()/2; 107 for(var box in this.boxs){ 108 if(st >= this.boxs[box]-parseInt(wH/2)){ 109 var $parent = this.$ele.find('a[href="#'+box+'"]').parent(); 110 this.changeNav(this,$parent); 111 } 112 }; 113 114 }, 115 116 //点击切换 117 clickSwitch: function(e){ 118 var $a = $(e.currentTarget); //获得当前的a 119 var $parent = $a.parent(); //获得a的li元素 120 var self = this; 121 var target = $a.attr("href"); //新的a #id 122 if(!$parent.hasClass(self.options.current)){ 123 //导航切换 124 self.changeNav(self,$parent); 125 126 //滚动开始 127 self.scrollTo(target, function(){ 128 //callback 129 }); 130 131 } 132 133 e.preventDefault(); //有current阻止冒泡 134 }, 135 136 //滚动到某个地方 137 scrollTo: function(target, callback){ 138 //获取目标元素的TOP值 139 var offset = $(target).offset().top; 140 var $el = $('html,body'); 141 if(!$el.is(":animated")){ 142 $el.animate({ 143 scrollTop: offset 144 }, this.options.speed, this.options.easing,callback); 145 } 146 } 147 }; 148 149 $.fn.navScrollSpy = function(options){ 150 return this.each(function(){ 151 if(!$.data(this, "plugin_"+pluginName)){ 152 $.data(this, "plugin_"+pluginName,new navScrollSpy(this, options)); 153 } 154 }); 155 }; 156 157 })(jQuery, window, document);
(3)<script src="sideNav.js"></script>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 $("#nav").navScrollSpy({ 2 navContainer: '#nav', 3 current:"current", 4 scrollSpeed: 50 5 });
css代码部分:
<style> *{margin:0; padding:0;} .header{width:100%; height:60px; background:#fff;} .help-banner{width:100%; height:80px; background:#e52e17;} .help-banner h2{font-size:24px; color:#fff; line-height:24px; padding:26px 0 26px 30px;} .help-container{margin-top:160px;} #nav{position:absolute; top:180px; left:70px;} ul,li{list-style-type:none;} .btn{width:160px; display:block; height:40px; line-height:40px; font-size:14px; font-weight:normal; text-align:center; border:1px solid #fe5050; border-radius:3px; cursor:pointer; -webkit-transition: background ease .2s, color ease .2s;} #nav li{margin-bottom:10px;} #nav li a{color:#333; text-decoration: none;} #nav li.current a{background:#fe5050; color:#fff;} .help-content{float:right; display:inline-block;} .help-content section{width:700px; height:600px; margin-bottom:20px;} </style>
HTML body代码部分:
<div class="header"> </div> <div class="help"> <div class="help-banner"> <h2>常见问题</h2> </div> <div class="help-container"> <ul id="nav" class="help-nav"> <li class="current"><a class="btn" href="#c1">导航一</a></li> <li><a class="btn" href="#c2">导航二</a></li> <li><a class="btn" href="#c3">导航三</a></li> <li><a class="btn" href="#c4">导航四</a></li> </ul> <div class="help-content"> <section id="c1"> <h2>导航一</h2> <div class="content"> 111111111111 111111111111111111111111111111111111 通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框 111111111111111111111111111111111111111111111111 111111111111 </div> </section> <section id="c2"> <h2>导航二</h2> <div class="content"> 222222222222222222222222222222222222 222222222222222222222222222222222222 通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-op通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框en 类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框 222222222222222222222222222222222222 222222222222222222222222222222222222 </div> </section> <section id="c3"> <h2>导航三</h2> <div class="content"> 333333333333333333333333333333 333333333333333333333333333333 通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框 333333333333333333333333333333 333333333333333333333333333333 </div> </section> <section id="c4"> <h2>导航四</h2> <div class="content"> 444444444444444444444444444444 444444444444444444444444444444 通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,从通过 data 属性或 JavaScript 调用模态框插件,可以根据需要动态展示隐藏的内容。模态框弹出时还会为 元素添加 .modal-open 类,从而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框而覆盖页面默认的滚动行为,并且还会自动生成一个 .modal-backdrop 元素用于提供一个可点击的区域,点击此区域就即可关闭模态框 444444444444444444444444444444 444444444444444444444444444444 </div> </section> </div> </div> </div>
JavaScript代码部分:
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="jquery.navScrollSpy.js"></script> <script src="sideNav.js"></script>
效果图:
随着内容的滚动左侧的导航栏内容也淘宝变化: