当前位置:首页 > 日记 > 正文

Bootstrap滚动监听组件scrollspy.js使用方法详解

Bootstrap滚动监听组件scrollspy.js使用方法详解

其实滚动监听使用的情况还是很多的,比如导航居于右侧,当主题内容滚动某一块的时候,右侧导航对应的要高亮。

实现功能

1、当滚动区域内设置的hashkey距离顶点到有效位置时,就关联设置其导航上的指定项
2、导航必须是 .nav > li > a 结构,并且a上href或data-target要绑定hashkey
3、菜单上必须有.nav样式
4、滚动区域的data-target与导航父级Id(一定是父级)要一致。

<div id="selector" class="navbar navbar-default"> <ul class="nav navbar-nav"> <li><a href="#one">one</a> </li> <li><a href="#two">two</a> </li> <li><a href="#three">three</a> </li> </ul></div><div data-spy="scroll" data-target="#selector" style="height:100px; overflow:hidden;overflow-y: auto;" > <h4 id="one" >ibe</h4><p>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/></p> <h4 id="two" >two</h4><p>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/></p> <h4 id="three" >three</h4><p>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/>One的具体内容<br/></p></div>

下面来看一下实现的具体代码,原理:当滚动容器内的hashkey位置距离容器顶部只有 offset设置的值,就会设置导航中对应的href高亮。

ScrollSpy构造函数

首先新建一个构造函数,如下:

function ScrollSpy(element, options) {  this.$body     = $(document.body)  this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)  this.options    = $.extend({}, ScrollSpy.DEFAULTS, options)  this.selector    = (this.options.target || '') + ' .nav li > a'  this.offsets    = []  this.targets    = []  this.activeTarget  = null  this.scrollHeight  = 0  this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))  this.refresh()  this.process() }

该构造函数主要干了啥:

1.基本设置,主要是设置当前滚动元素是设置的body还是具体的某一块元素;其次是导航的结构要是.nav li > a的结构,也就是你的菜单中也要有.nav这个class。

2.监听元素滚动的时候,执行process方法。

3.同时初始化的时候也执行了refresh与process方法。

下面讲解一下这几个方法。

getScrolHeight方法

获取滚动容器的内容高度(包含被隐藏部分)

this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)

refresh方法

刷新并存储滚动容器内各hashkey的值

ScrollSpy.prototype.refresh = function () {  var that     = this  var offsetMethod = 'offset'  var offsetBase  = 0  this.offsets   = []  this.targets   = []  this.scrollHeight = this.getScrollHeight()  if (!$.isWindow(this.$scrollElement[0])) {   offsetMethod = 'position'   offsetBase  = this.$scrollElement.scrollTop()  }  this.$body   .find(this.selector)   .map(function () {    var $el  = $(this)    var href = $el.data('target') || $el.attr('href')    var $href = /^#./.test(href) && $(href)        return ($href     && $href.length     && $href.is(':visible')     && [[$href[offsetMethod]().top + offsetBase, href]]) || null   })   .sort(function (a, b) { return a[0] - b[0] })   .each(function () {    that.offsets.push(this[0])    that.targets.push(this[1])   }) }

它主要实现了什么呢?

1.默认用offset来获取定位值,如果滚动区域不是window则用position来获取

if (!$.isWindow(this.$scrollElement[0])) {   offsetMethod = 'position'   offsetBase  = this.$scrollElement.scrollTop()  }

2.根据导航上的hashkey来遍历获取 滚动区域内的hashkey对应的offset值:

this.$body   .find(this.selector)   .map(function () {    var $el  = $(this)    var href = $el.data('target') || $el.attr('href')    var $href = /^#./.test(href) && $(href)        return ($href     && $href.length     && $href.is(':visible')     && [[$href[offsetMethod]().top + offsetBase, href]]) || null   })   .sort(function (a, b) { return a[0] - b[0] })   .each(function () {    that.offsets.push(this[0])    that.targets.push(this[1])   })

process方法

滚动条事件触发函数,用于计算当前需要高亮那个导航菜单

ScrollSpy.prototype.process = function () {  var scrollTop  = this.$scrollElement.scrollTop() + this.options.offset  var scrollHeight = this.getScrollHeight()  var maxScroll  = this.options.offset + scrollHeight - this.$scrollElement.height()  var offsets   = this.offsets  var targets   = this.targets  var activeTarget = this.activeTarget  var i  if (this.scrollHeight != scrollHeight) {   this.refresh()  }  if (scrollTop >= maxScroll) {   return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)  }  if (activeTarget && scrollTop < offsets[0]) {   this.activeTarget = null   return this.clear()  }  for (i = offsets.length; i--;) {   activeTarget != targets[i]    && scrollTop >= offsets[i]    && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])    && this.activate(targets[i])  } }

主要作用:

1.获取滚动容器已滚动距离:

var scrollTop  = this.$scrollElement.scrollTop() + this.options.offset

2.滚动容器可以滚动的最大高度:

var maxScroll  = this.options.offset + scrollHeight - this.$scrollElement.height()

3.设置滚动元素逻辑,给当前匹配元素添加高亮:

for (i = offsets.length; i--;) {   activeTarget != targets[i]    && scrollTop >= offsets[i]    && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])    && this.activate(targets[i])  }

active方法

设置指定的导航菜单高亮

ScrollSpy.prototype.activate = function (target) {  this.activeTarget = target  this.clear()  var selector = this.selector +   '[data-target="' + target + '"],' +   this.selector + '[href="' + target + '" rel="external nofollow" rel="external nofollow" ]'  var active = $(selector)   .parents('li')   .addClass('active')  if (active.parent('.dropdown-menu').length) {   active = active    .closest('li.dropdown')    .addClass('active')  }  active.trigger('activate.bs.scrollspy') }

clear方法

清除所有高亮菜单

ScrollSpy.prototype.clear = function () {  $(this.selector)   .parentsUntil(this.options.target, '.active')   .removeClass('active') }

 源码

+function ($) { 'use strict'; // SCROLLSPY CLASS DEFINITION // ========================== function ScrollSpy(element, options) {  this.$body     = $(document.body)  this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)  this.options    = $.extend({}, ScrollSpy.DEFAULTS, options)  this.selector    = (this.options.target || '') + ' .nav li > a'  this.offsets    = []  this.targets    = []  this.activeTarget  = null  this.scrollHeight  = 0  this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))  this.refresh()  this.process() } ScrollSpy.VERSION = '3.3.7' ScrollSpy.DEFAULTS = {  offset: 10 } ScrollSpy.prototype.getScrollHeight = function () {  return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) } ScrollSpy.prototype.refresh = function () {  var that     = this  var offsetMethod = 'offset'  var offsetBase  = 0  this.offsets   = []  this.targets   = []  this.scrollHeight = this.getScrollHeight()  if (!$.isWindow(this.$scrollElement[0])) {   offsetMethod = 'position'   offsetBase  = this.$scrollElement.scrollTop()  }  this.$body   .find(this.selector)   .map(function () {    var $el  = $(this)    var href = $el.data('target') || $el.attr('href')    var $href = /^#./.test(href) && $(href)        return ($href     && $href.length     && $href.is(':visible')     && [[$href[offsetMethod]().top + offsetBase, href]]) || null   })   .sort(function (a, b) { return a[0] - b[0] })   .each(function () {    that.offsets.push(this[0])    that.targets.push(this[1])   }) } ScrollSpy.prototype.process = function () {  var scrollTop  = this.$scrollElement.scrollTop() + this.options.offset  var scrollHeight = this.getScrollHeight()  var maxScroll  = this.options.offset + scrollHeight - this.$scrollElement.height()  var offsets   = this.offsets  var targets   = this.targets  var activeTarget = this.activeTarget  var i  if (this.scrollHeight != scrollHeight) {   this.refresh()  }  if (scrollTop >= maxScroll) {   return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)  }  if (activeTarget && scrollTop < offsets[0]) {   this.activeTarget = null   return this.clear()  }  for (i = offsets.length; i--;) {   activeTarget != targets[i]    && scrollTop >= offsets[i]    && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])    && this.activate(targets[i])  } } ScrollSpy.prototype.activate = function (target) {  this.activeTarget = target  this.clear()  var selector = this.selector +   '[data-target="' + target + '"],' +   this.selector + '[href="' + target + '" rel="external nofollow" rel="external nofollow" ]'  var active = $(selector)   .parents('li')   .addClass('active')  if (active.parent('.dropdown-menu').length) {   active = active    .closest('li.dropdown')    .addClass('active')  }  active.trigger('activate.bs.scrollspy') } ScrollSpy.prototype.clear = function () {  $(this.selector)   .parentsUntil(this.options.target, '.active')   .removeClass('active') } // SCROLLSPY PLUGIN DEFINITION // =========================== function Plugin(option) {  return this.each(function () {   var $this  = $(this)   var data  = $this.data('bs.scrollspy')   var options = typeof option == 'object' && option   if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))   if (typeof option == 'string') data[option]()  }) } var old = $.fn.scrollspy $.fn.scrollspy       = Plugin $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function () {  $.fn.scrollspy = old  return this } // SCROLLSPY DATA-API // ================== $(window).on('load.bs.scrollspy.data-api', function () {  $('[data-spy="scroll"]').each(function () {   var $spy = $(this)   Plugin.call($spy, $spy.data())  }) })}(jQuery);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关文章

PS鼠绘一把超逼真的金属质感弯刀

PS鼠绘一把超逼真的金属质感弯刀

弯刀,质感,超逼真,电脑软件,PS,这篇教程教的PS鼠绘学习者们使用PS鼠绘超强质感弯刀,教程主要介绍的使用PS来体现弯刀的金属质感和锋利。对于学习鼠绘的朋友来说还是挺有用的,推荐过来和的朋友们一起分享,一起学习了,我们先来看看最终的效果图:下…

创建一般js对象的几种方式

创建一般js对象的几种方式

对象,几种,方式,电脑软件,js,1.对象字面量创建对象var obj = { a:1,b:2 };注意:对象字面量是一个表达式,这种表达式每次运算都会创建并初始化一个新对象,并计算这个新对象的每个属性值。所以如果在循环体内使用对象字面量,每次循环时都会创建新…

ai怎么绘制多重线条?

ai怎么绘制多重线条?

绘制,多重,线条,电脑软件,ai,AI线条的变化可以绘制出很多的图形,下面我们就来看看简单的例子。软件名称:Adobe Illustrator CS6 (AI cs6) 精简绿色中文版(32位+64位)软件大小:205MB更新时间:2014-05-111、新建一个图层2、选矩形工具画矩形设置…

excel表格怎么设置页数excel表格设

excel表格怎么设置页数excel表格设

设置,步骤,方法,页数,表格,  Excel表格中怎么设置页数,其实这很简单只要你跟着着小编的的步骤来学习,很快学会的。excel表格设置页数的步骤首先点开EXCEL表格,比如说你要写六页纸,就用鼠标圈出六个工作表。然后点击开始,开始里面有框线设置,比…

javascript算法之二叉搜索树的示例

javascript算法之二叉搜索树的示例

算法,示例代码,二叉搜索树,电脑软件,javascript,什么是二叉树二叉树就是树的每个节点最多只能有两个子节点什么是二叉搜索树二叉搜索树在二叉树的基础上,多了一个条件,就是二叉树在插入值时,若插入值比当前节点小,就插入到左节点,否则插入到右节…

NodeJS设计模式总结【单例模式,适

NodeJS设计模式总结【单例模式,适

设计模式,单例模式,装饰模式,适配器模式,观察者模式,本文实例讲述了NodeJS设计模式。分享给大家供大家参考,具体如下:1 . 单例模式顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直接返回,若不存在,则创建实…

WPS文字怎么删除表格后空白页

WPS文字怎么删除表格后空白页

删除表,文字,格后,方法,空白页,  表格后的空白页删不掉让人烦恼,那么表格后的空白页该怎样去掉呢?以下是小编给大家整理的WPS文字去掉表格后空白页的技巧,希望能帮到你!WPS文字删除表格后空白页的方法难道就真的没有办法去掉这可恶的空白页…

Spring AOP的实现原理详解及实例

Spring AOP的实现原理详解及实例

实现原理,详解,实例,电脑软件,Spring,Spring AOP的实现原理详解及实例spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。以下是JDK动态代理和CGLIB代理简单介绍 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一…

angular2+node.js express打包部署

angular2+node.js express打包部署

实战,电脑软件,node,express,js,Angular2我自己还在摸索学习中,本文介绍了angular2+node.js express打包部署的实战,分享给大家,也给自己留个笔记angular是客户端js,Node.js 是服务端JS,建立SPA 网站需要把这两者统一到一起。1、angular2项目…

怎么样用word绘制表格用word绘制表

怎么样用word绘制表格用word绘制表

绘制,步骤,方法,表格,电脑软件,  word已经普及人们的生活,可以用word来制作个人简历、制作1篇文章、制作1张电子小报亦或是论文等等,下面小编来教大家如何用word绘制1张简单的表格。word绘制表格的步骤这是我绘制的1张简单表格大家只要知道…

怎么恢复excel2010没有保存的文件

怎么恢复excel2010没有保存的文件

文件,恢复,电脑软件,  恢复excel2010没有保存的文件,有时我们太匆忙了,把Excel做到一半的时候我们忘记点击保存,就直接把它给关了,再打开的时候就老是显示不出来了,就没有了。以下是小编为您带来的关于恢复excel2010没有保存的文件,希望对您有…

PHP框架laravel的.env文件配置教程

PHP框架laravel的.env文件配置教程

配置,文件,框架,教程,电脑软件,前言大家应该都知道使用laravel框架开发PHP程序的时候,配置框架的.env文件是至关重要的,这个文件上需要配置数据库、数据库用户以及缓存等,下面来一起看看详细的配置教程。一、配置APP_KEYlaravel框架默认在.env…