selectnav.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * @preserve SelectNav.js (v. 0.1)
  3. * Converts your <ul>/<ol> navigation into a dropdown list for small screens
  4. * https://github.com/lukaszfiszer/selectnav.js
  5. */
  6. window.selectnav = (function(){
  7. "use strict";
  8. var selectnav = function(element,options){
  9. element = document.getElementById(element);
  10. // return immediately if element doesn't exist
  11. if( ! element){
  12. return;
  13. }
  14. // return immediately if element is not a list
  15. if( ! islist(element) ){
  16. return;
  17. }
  18. // add a js class to <html> tag
  19. document.documentElement.className += " js";
  20. // retreive options and set defaults
  21. var o = options || {},
  22. activeclass = o.activeclass || 'active',
  23. autoselect = typeof(o.autoselect) === "boolean" ? o.autoselect : true,
  24. nested = typeof(o.nested) === "boolean" ? o.nested : true,
  25. indent = o.indent || "→",
  26. label = o.label || "- Navigation -",
  27. // helper variables
  28. level = 0,
  29. selected = " selected ";
  30. // insert the freshly created dropdown navigation after the existing navigation
  31. element.insertAdjacentHTML('afterend', parselist(element) );
  32. var nav = document.getElementById(id());
  33. // autoforward on click
  34. if (nav.addEventListener) {
  35. nav.addEventListener('change',goTo);
  36. }
  37. if (nav.attachEvent) {
  38. nav.attachEvent('onchange', goTo);
  39. }
  40. return nav;
  41. function goTo(e){
  42. // Crossbrowser issues - http://www.quirksmode.org/js/events_properties.html
  43. var targ;
  44. if (!e) e = window.event;
  45. if (e.target) targ = e.target;
  46. else if (e.srcElement) targ = e.srcElement;
  47. if (targ.nodeType === 3) // defeat Safari bug
  48. targ = targ.parentNode;
  49. if(targ.value) window.location.href = targ.value;
  50. }
  51. function islist(list){
  52. var n = list.nodeName.toLowerCase();
  53. return (n === 'ul' || n === 'ol');
  54. }
  55. function id(nextId){
  56. for(var j=1; document.getElementById('selectnav'+j);j++);
  57. return (nextId) ? 'selectnav'+j : 'selectnav'+(j-1);
  58. }
  59. function parselist(list){
  60. // go one level down
  61. level++;
  62. var length = list.children.length,
  63. html = '',
  64. prefix = '',
  65. k = level-1
  66. ;
  67. // return immediately if has no children
  68. if (!length) {
  69. return;
  70. }
  71. if(k) {
  72. while(k--){
  73. prefix += indent;
  74. }
  75. prefix += " ";
  76. }
  77. for(var i=0; i < length; i++){
  78. var link = list.children[i].children[0];
  79. if(typeof(link) !== 'undefined'){
  80. var text = link.innerText || link.textContent;
  81. var isselected = '';
  82. if(activeclass){
  83. isselected = link.className.search(activeclass) !== -1 || link.parentElement.className.search(activeclass) !== -1 ? selected : '';
  84. }
  85. if(autoselect && !isselected){
  86. isselected = link.href === document.URL ? selected : '';
  87. }
  88. html += '<option value="' + link.href + '" ' + isselected + '>' + prefix + text +'</option>';
  89. if(nested){
  90. var subElement = list.children[i].children[1];
  91. if( subElement && islist(subElement) ){
  92. html += parselist(subElement);
  93. }
  94. }
  95. }
  96. }
  97. // adds label
  98. if(level === 1 && label) {
  99. html = '<option value="">' + label + '</option>' + html;
  100. }
  101. // add <select> tag to the top level of the list
  102. if(level === 1) {
  103. html = '<select class="selectnav" id="'+id(true)+'">' + html + '</select>';
  104. }
  105. // go 1 level up
  106. level--;
  107. return html;
  108. }
  109. };
  110. return function (element,options) {
  111. selectnav(element,options);
  112. };
  113. })();