| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * @file sidenav.js
- * @author Jianlong Chen <jianlong99@gmail.com>
- * @date 2014-03-08
- * @update 2014-11-12
- */
- (function($) {
- 'use strict';
- function SideNav($el) {
- this.$el = $el;
- }
- SideNav.prototype = {
- constructor: SideNav,
- init: function(options) {
- this.options = options;
- this.initViews();
- this.initAffix();
- },
- initViews: function() {
- var that = this,
- counts = {},
- preLevel = 0,
- parentId = '';
- this.$menu = $([
- '<div class="bs-sidebar hidden-print">',
- ' <ul class="nav bs-sidenav">',
- ' </ul>',
- '</div>'
- ].join(''));
- this.$list = '';
- // Support String type, for example use: data-hs="h1, h2, h3"
- if (typeof this.options.hs === 'string') {
- this.options.hs = $.map(this.options.hs.split(','), function (h) {
- return $.trim(h); // remove space
- });
- }
- this.$el.find(this.options.hs.join(',')).each(function(i) {
- var $this = $(this),
- $div,
- name = $this[0].localName,
- title = $this.text(),
- level = $.inArray(name, that.options.hs) + 1,
- nums = [],
- index,
- id;
- if (level - preLevel > 1) {
- return;
- }
- if (!counts.hasOwnProperty(name) || level - preLevel === 1) {
- counts[name] = 0;
- }
- counts[name]++;
- $.each(counts, function(i) {
- nums.push(counts[i]);
- if (nums.length === level) {
- return false;
- }
- });
- index = nums.join('-');
- id = 'sideNavTitle' + index;
- if (that.options.smartId) {
- id = $.trim($(this).text()).toLowerCase();
- id = id.replace(/ /g, '-');
- id = id.replace(/'|"/g, '');
- if (level === 2) {
- id = parentId + '-' + id;
- }
- }
- $div = $('<div id="' + id + '"></div>');
- $div.insertAfter($this).append($this);
- var aElem = '<a href="#' + id + '">' + title + '</a>';
- if (level === 1 && preLevel === 0) {
- that.$list += '<li class="active">' + aElem;
- } else if (level === preLevel) {
- that.$list += '</li><li>' + aElem;
- } else if (level - preLevel === 1) {
- that.$list += '<ul class="nav"><li>' + aElem;
- } else {
- for (var $i = 0; $i < preLevel - level; $i++) {
- that.$list += '</ul></li>';
- }
- that.$list += '<li>' + aElem;
- }
- if (level === 1) {
- parentId = id;
- }
- preLevel = level;
- });
- for (; preLevel > 0; preLevel--) {
- if (preLevel > 1) {
- that.$list += '</ul>';
- }
- that.$list += '</li>';
- }
- this.$menu.find('ul').append(this.$list);
- var backElem = '<a class="back-to-top" href="' +
- this.options.toTopHref + '">' + this.options.toTopText + '</a>';
- this.$menu.append(backElem);
- $(this.options.container).append(this.$menu);
- },
- initAffix: function() {
- $('body').scrollspy({target: '.bs-sidebar'});
- if (typeof this.options.top === 'undefined') {
- this.options.top = this.options.container;
- }
- if (typeof this.options.top === 'string' && $(this.options.top).length) {
- this.options.top = $(this.options.top).offset().top;
- }
- if (typeof this.options.bottom === 'string' && $(this.options.bottom).length) {
- this.options.bottom = $(this.options.bottom).outerHeight(true);
- }
- this.$menu.affix({
- offset: {
- top: this.options.top || 0,
- bottom: this.options.bottom || 0
- }
- });
- }
- };
- $.fn.sideNav = function() {
- var option = arguments[0],
- args = arguments,
- value;
- this.each(function() {
- var $this = $(this), data = $this.data('sideNav'),
- options = $.extend({}, $.fn.sideNav.defaults, $this.data(), option);
- if (!data) {
- data = new SideNav($this);
- data.init(options, true);
- $this.data('sideNav', data);
- } else {
- data.init(options);
- }
- });
- return value ? value : this;
- };
- $.fn.sideNav.defaults = {
- container: 'body',
- hs: ['h2', 'h3', 'h4'],
- smartId: false,
- top: undefined,
- bottom: undefined,
- toTopHref: '#top',
- toTopText: 'Back to top'
- };
- $(function () {
- $('[data-toggle="sidenav"]').sideNav();
- });
- })(jQuery);
|