corrade-nucleus-nucleons – Blame information for rev 20
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
20 | office | 1 | /* |
2 | * @file sidenav.js |
||
3 | * @author Jianlong Chen <jianlong99@gmail.com> |
||
4 | * @date 2014-03-08 |
||
5 | * @update 2014-11-12 |
||
6 | */ |
||
7 | |||
8 | (function($) { |
||
9 | |||
10 | 'use strict'; |
||
11 | |||
12 | function SideNav($el) { |
||
13 | this.$el = $el; |
||
14 | } |
||
15 | |||
16 | |||
17 | SideNav.prototype = { |
||
18 | constructor: SideNav, |
||
19 | |||
20 | init: function(options) { |
||
21 | this.options = options; |
||
22 | |||
23 | this.initViews(); |
||
24 | this.initAffix(); |
||
25 | }, |
||
26 | |||
27 | initViews: function() { |
||
28 | var that = this, |
||
29 | counts = {}, |
||
30 | preLevel = 0, |
||
31 | parentId = ''; |
||
32 | |||
33 | this.$menu = $([ |
||
34 | '<div class="bs-sidebar hidden-print">', |
||
35 | ' <ul class="nav bs-sidenav">', |
||
36 | ' </ul>', |
||
37 | '</div>' |
||
38 | ].join('')); |
||
39 | this.$list = ''; |
||
40 | |||
41 | // Support String type, for example use: data-hs="h1, h2, h3" |
||
42 | if (typeof this.options.hs === 'string') { |
||
43 | this.options.hs = $.map(this.options.hs.split(','), function (h) { |
||
44 | return $.trim(h); // remove space |
||
45 | }); |
||
46 | } |
||
47 | |||
48 | this.$el.find(this.options.hs.join(',')).each(function(i) { |
||
49 | var $this = $(this), |
||
50 | $div, |
||
51 | name = $this[0].localName, |
||
52 | title = $this.text(), |
||
53 | level = $.inArray(name, that.options.hs) + 1, |
||
54 | nums = [], |
||
55 | index, |
||
56 | id; |
||
57 | |||
58 | if (level - preLevel > 1) { |
||
59 | return; |
||
60 | } |
||
61 | if (!counts.hasOwnProperty(name) || level - preLevel === 1) { |
||
62 | counts[name] = 0; |
||
63 | } |
||
64 | counts[name]++; |
||
65 | |||
66 | $.each(counts, function(i) { |
||
67 | nums.push(counts[i]); |
||
68 | if (nums.length === level) { |
||
69 | return false; |
||
70 | } |
||
71 | }); |
||
72 | index = nums.join('-'); |
||
73 | |||
74 | id = 'sideNavTitle' + index; |
||
75 | |||
76 | if (that.options.smartId) { |
||
77 | id = $.trim($(this).text()).toLowerCase(); |
||
78 | id = id.replace(/ /g, '-'); |
||
79 | id = id.replace(/'|"/g, ''); |
||
80 | if (level === 2) { |
||
81 | id = parentId + '-' + id; |
||
82 | } |
||
83 | } |
||
84 | $div = $('<div id="' + id + '"></div>'); |
||
85 | $div.insertAfter($this).append($this); |
||
86 | |||
87 | var aElem = '<a href="#' + id + '">' + title + '</a>'; |
||
88 | if (level === 1 && preLevel === 0) { |
||
89 | that.$list += '<li class="active">' + aElem; |
||
90 | } else if (level === preLevel) { |
||
91 | that.$list += '</li><li>' + aElem; |
||
92 | } else if (level - preLevel === 1) { |
||
93 | that.$list += '<ul class="nav"><li>' + aElem; |
||
94 | } else { |
||
95 | for (var $i = 0; $i < preLevel - level; $i++) { |
||
96 | that.$list += '</ul></li>'; |
||
97 | } |
||
98 | that.$list += '<li>' + aElem; |
||
99 | } |
||
100 | if (level === 1) { |
||
101 | parentId = id; |
||
102 | } |
||
103 | preLevel = level; |
||
104 | }); |
||
105 | |||
106 | for (; preLevel > 0; preLevel--) { |
||
107 | if (preLevel > 1) { |
||
108 | that.$list += '</ul>'; |
||
109 | } |
||
110 | that.$list += '</li>'; |
||
111 | } |
||
112 | this.$menu.find('ul').append(this.$list); |
||
113 | |||
114 | var backElem = '<a class="back-to-top" href="' + |
||
115 | this.options.toTopHref + '">' + this.options.toTopText + '</a>'; |
||
116 | this.$menu.append(backElem); |
||
117 | |||
118 | $(this.options.container).append(this.$menu); |
||
119 | }, |
||
120 | |||
121 | initAffix: function() { |
||
122 | $('body').scrollspy({target: '.bs-sidebar'}); |
||
123 | |||
124 | if (typeof this.options.top === 'undefined') { |
||
125 | this.options.top = this.options.container; |
||
126 | } |
||
127 | if (typeof this.options.top === 'string' && $(this.options.top).length) { |
||
128 | this.options.top = $(this.options.top).offset().top; |
||
129 | } |
||
130 | if (typeof this.options.bottom === 'string' && $(this.options.bottom).length) { |
||
131 | this.options.bottom = $(this.options.bottom).outerHeight(true); |
||
132 | } |
||
133 | this.$menu.affix({ |
||
134 | offset: { |
||
135 | top: this.options.top || 0, |
||
136 | bottom: this.options.bottom || 0 |
||
137 | } |
||
138 | }); |
||
139 | } |
||
140 | }; |
||
141 | |||
142 | $.fn.sideNav = function() { |
||
143 | var option = arguments[0], |
||
144 | args = arguments, |
||
145 | value; |
||
146 | |||
147 | this.each(function() { |
||
148 | var $this = $(this), data = $this.data('sideNav'), |
||
149 | options = $.extend({}, $.fn.sideNav.defaults, $this.data(), option); |
||
150 | |||
151 | if (!data) { |
||
152 | data = new SideNav($this); |
||
153 | data.init(options, true); |
||
154 | $this.data('sideNav', data); |
||
155 | } else { |
||
156 | data.init(options); |
||
157 | } |
||
158 | }); |
||
159 | |||
160 | return value ? value : this; |
||
161 | }; |
||
162 | |||
163 | $.fn.sideNav.defaults = { |
||
164 | container: 'body', |
||
165 | hs: ['h2', 'h3', 'h4'], |
||
166 | smartId: false, |
||
167 | top: undefined, |
||
168 | bottom: undefined, |
||
169 | toTopHref: '#top', |
||
170 | toTopText: 'Back to top' |
||
171 | }; |
||
172 | |||
173 | $(function () { |
||
174 | $('[data-toggle="sidenav"]').sideNav(); |
||
175 | }); |
||
176 | })(jQuery); |