forked from daudmabena/selectnav.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathselectnav.js
More file actions
156 lines (117 loc) · 3.84 KB
/
selectnav.js
File metadata and controls
156 lines (117 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* @preserve SelectNav.js (v. 0.1)
* Converts your <ul>/<ol> navigation into a dropdown list for small screens
* https://github.com/lukaszfiszer/selectnav.js
*/
window.selectnav = (function(){
"use strict";
var selectnav = function(element,options){
element = document.getElementById(element);
// return immediately if element doesn't exist
if( ! element){
return;
}
// return immediately if element is not a list
if( ! islist(element) ){
return;
}
// return immediately if no support for insertAdjacentHTML (Firefox 7 and under)
if( ! ('insertAdjacentHTML' in window.document.documentElement) ){
return;
}
// add a js class to <html> tag
document.documentElement.className += " js";
// retreive options and set defaults
var o = options || {},
activeclass = o.activeclass || 'active',
autoselect = typeof(o.autoselect) === "boolean" ? o.autoselect : true,
nested = typeof(o.nested) === "boolean" ? o.nested : true,
indent = o.indent || "→",
label = o.label || "- Navigation -",
// helper variables
level = 0,
selected = " selected ";
// insert the freshly created dropdown navigation after the existing navigation
element.insertAdjacentHTML('afterend', parselist(element) );
var nav = document.getElementById(id());
// autoforward on click
if (nav.addEventListener) {
nav.addEventListener('change',goTo);
}
if (nav.attachEvent) {
nav.attachEvent('onchange', goTo);
}
return nav;
function goTo(e){
// Crossbrowser issues - http://www.quirksmode.org/js/events_properties.html
var targ;
if (!e) e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType === 3) // defeat Safari bug
targ = targ.parentNode;
if(targ.value) window.location.href = targ.value;
}
function islist(list){
var n = list.nodeName.toLowerCase();
return (n === 'ul' || n === 'ol');
}
function id(nextId){
for(var j=1; document.getElementById('selectnav'+j);j++);
return (nextId) ? 'selectnav'+j : 'selectnav'+(j-1);
}
function parselist(list){
// go one level down
level++;
var length = list.children.length,
html = '',
prefix = '',
k = level-1
;
// return immediately if has no children
if (!length) {
return;
}
if(k) {
while(k--){
prefix += indent;
}
prefix += " ";
}
for(var i=0; i < length; i++){
var link = list.children[i].children[0];
if(typeof(link) !== 'undefined'){
var text = link.innerText || link.textContent;
var isselected = '';
if(activeclass){
isselected = link.className.search(activeclass) !== -1 || link.parentNode.className.search(activeclass) !== -1 ? selected : '';
}
if(autoselect && !isselected){
isselected = link.href === document.URL ? selected : '';
}
html += '<option value="' + link.href + '" ' + isselected + '>' + prefix + text +'</option>';
if(nested){
var subElement = list.children[i].children[1];
if( subElement && islist(subElement) ){
html += parselist(subElement);
}
}
}
}
// adds label
if(level === 1 && label) {
html = '<option value="">' + label + '</option>' + html;
}
// add <select> tag to the top level of the list
if(level === 1) {
html = '<select class="selectnav" id="'+id(true)+'">' + html + '</select>';
}
// go 1 level up
level--;
return html;
}
};
return function (element,options) {
return selectnav(element,options);
};
})();