PageSourceSearch

https://www.karmanos.org/Uploads/JS/jquery-accessible-subnav-dropdown.js

js karmanos.org collected 2026-09-24 19:52:19 UTC 20,163 bytes, 544 lines download raw bytes

1$(document).ready(function() {
2
3   /*
4    * jQuery accessible and keyboard-enhanced navigation with dropdown
5    * Website: http://a11y.nicolas-hoffmann.net/subnav-dropdown/
6    * License MIT: https://github.com/nico3333fr/jquery-accessible-subnav-dropdown/blob/master/LICENSE
7    */
8   // loading expand paragraphs
9   var $nav_system = $('.page-nav'),
10       $body = $('body');
11   if ($nav_system.length) { // if there is at least one :)
12
13      // initialization
14      var $nav_system_link = $('.page-nav__link');
15      var $subNav_system_link = $('.page-nav__subnav__link');
16
17      $nav_system_link.each(function(index_to_expand) {
18         var $this = $(this),
19             index_lisible = index_to_expand + 1,
20             $subnav = $this.next('.page-nav__subnav'),
21             full_path = location.href.split("#")[0],
22             $parent_item = $this.parents('.page-nav__item');
23
24         // if there is a subnav adjacent to the link
25         if ($subnav.length === 1) {
26            $subnav.attr({
27               'data-visually-hidden': 'true'
28            });
29         }
30
31         //Open subnav section if it's corresponding link is active
32         // if ($this.prop("href").split("#")[0] == full_path) {
33         //   $parent_item.attr({
34         //     'data-show-sub': 'true'
35         //   });
36         //
37         //   $subnav.attr({
38         //     'data-visually-hidden': 'false'
39         //   });
40         // }
41      });
42
43      $subNav_system_link.each(function(index_to_expand) {
44         var $this = $(this),
45             index_lisible = index_to_expand + 1,
46             $subnav = $this.next('.page-nav__subnav'),
47             full_path = location.href.split("#")[0],
48             $parent_item = $this.parents('.page-nav__subnav__item');
49
50         // if there is a subnav adjacent to the link
51         if ($subnav.length === 1) {
52            $subnav.attr({
53               'data-visually-hidden': 'true'
54            });
55            // Open subnav section if it's corresponding link is active
56            // if ($this.prop("href").split("#")[0] == full_path) {
57            //   $parent_item.attr({
58            //     'data-show-sub': 'true'
59            //   });
60            //
61            //   $subnav.attr({
62            //     'data-visually-hidden': 'false'
63            //   });
64            // }
65         }
66      });
67   }
68
69
70
71
72       function enableNavHover(){
73           var desktopView = $(document).width();
74           if(desktopView >= "991"){
75             $body.on('mouseenter', '.full-width .page-nav__item', function(event) {
76                  var $this = $(this),
77                      $subnav_link = $this.children('.page-nav__link'),
78                      $subnav = $this.children('.page-nav__subnav');
79                      timer = setTimeout(function(){
80                        $this.attr({
81                           'data-show-sub': 'true'
82                        });
83
84                        // show submenu
85                        if ($subnav.length === 1) {
86                           $subnav.attr({
87                              'data-visually-hidden': 'false'
88                           });
89                        }
90                     },250)
91               })
92               .on('mouseleave', '.full-width .page-nav__item', function(event) {
93                  var $this = $(this),
94                      $subnav_link = $this.children('.page-nav__link'),
95                      $subnav = $this.children('.page-nav__subnav');
96                      // timer_leave = setTimeout(function({
97                        $this.attr({
98                           'data-show-sub': 'false'
99                        });
100                        // show submenu
101                        if ($subnav.length === 1) {
102                           $subnav.attr({
103                              'data-visually-hidden': 'true'
104                           });
105                        }
106                      clearTimeout(timer);
107               });
108           }else{
109             $body.on('mouseenter', '.full-width .page-nav__item', function(event) {
110
111               })
112               .on('mouseleave', '.full-width .page-nav__item', function(event) {
113
114               });
115             }
116           }
117
118
119
120
121
122
123   // events on main menu
124   // mouse !
125
126      // keyboard
127      $body.on('click', '.page-nav li > i', function(event) {
128               var $this = $(this),
129                   $parent = $this.parents('.page-nav'),
130                   $parent_item = $this.parents('.page-nav__item'),
131                   $parentSubNav_item = $this.parents('.page-nav__subnav__item'),
132                   $subnav = $this.prev('.page-nav__subnav');
133
134              //Toggle this item to plus or minus
135              $this.toggleClass('fa-minus fa-plus');
136
137              //Find other items and change plus to minus
138              $parent_item.siblings().find('i').removeClass('fa-minus').addClass('fa-plus');
139              $parentSubNav_item.siblings().find('i').removeClass('fa-minus').addClass('fa-plus');
140
141              $parent_item.siblings('.js-has-children').attr({
142                  'data-show-sub': 'false'
143              });
144
145               $parent_item.attr('data-show-sub', function (i, attr) {
146                  return attr == 'true' ? 'false' : 'true'
147                });
148
149               // hide other menus and show submenu activated
150               $parent_item.siblings().find('.page-nav__subnav').attr({
151                  'data-visually-hidden': 'true'
152               });
153
154                $parentSubNav_item.siblings().find('.page-nav__subnav').attr({
155                  'data-visually-hidden': 'true'
156               });
157
158
159               if ($subnav.length === 1) {
160                  $subnav.attr('data-visually-hidden', function (i, attr) {
161                    return attr == 'true' ? 'false' : 'true'
162                  });
163               }
164
165        })
166        .on('focus', '.page-nav__link', function(event) {
167         var $this = $(this),
168             $parent = $this.parents('.page-nav'),
169             $parent_item = $this.parents('.page-nav__item'),
170             $subnav = $this.next('.page-nav__subnav');
171
172         $parent_item.siblings().find('i').removeClass('fa-minus').addClass('fa-plus');
173
174         $this.siblings('i').toggleClass('fa-minus fa-plus');
175
176         $parent_item.attr({
177            'data-show-sub': 'true'
178         });
179
180         // hide other menus and show submenu activated
181         $parent.find('.page-nav__subnav').attr({
182            'data-visually-hidden': 'true'
183         });
184
185         if ($subnav.length === 1) {
186            $subnav.attr({
187               'data-visually-hidden': 'false'
188            });
189         }
190
191      })
192      .on('focusout', '.page-nav__link', function(event) {
193         var $this = $(this),
194             $parent = $this.parents('.page-nav'),
195             $parent_item = $this.parents('.page-nav__item');
196
197         $parent_item.attr({
198            'data-show-sub': 'false'
199         });
200      })
201      .on('keydown', '.page-nav__link', function(event) {
202         var $this = $(this),
203             $parent = $this.parents('.page-nav'),
204             $parent_item = $this.parents('.page-nav__item'),
205             $subnav = $this.next('.page-nav__subnav');
206
207         // event keyboard left
208         if (event.keyCode == 37) {
209            // select previous nav-system__link
210
211            // if we are on first => activate last
212            if ($parent_item.is(".page-nav__item:first-child")) {
213               $parent.find(" .page-nav__item:last-child ").children(".page-nav__link").focus();
214            }
215            // else activate previous
216            else {
217               $parent_item.prev().children(".page-nav__link").focus();
218            }
219            event.preventDefault();
220         }
221
222         // event keyboard right
223         if (event.keyCode == 39) {
224            // select previous nav-system__link
225
226            // if we are on last => activate first
227            if ($parent_item.is(".page-nav__item:last-child")) {
228               $parent.find(" .page-nav__item:first-child ").children(".page-nav__link").focus();
229            }
230            // else activate next
231            else {
232               $parent_item.next().children(".page-nav__link").focus();
233            }
234            event.preventDefault();
235         }
236
237         // event keyboard bottom
238         if (event.keyCode == 40) {
239            // select first nav-system__subnav__link
240            if ($subnav.length === 1) {
241               // if submenu has been closed => reopen
242               $subnav.attr({
243                  'data-visually-hidden': 'false'
244               });
245               // and select first item
246               $subnav.find(" .page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
247            }
248            event.preventDefault();
249         }
250
251         // event shift + tab
252         if (event.shiftKey && event.keyCode == 9) {
253            if ($parent_item.is(".page-nav__item:first-child")) {
254               $subnav.attr({
255                  'data-visually-hidden': 'true'
256               });
257            } else {
258
259               var $prev_nav_link = $parent_item.prev('.page-nav__item').children(".page-nav__link");
260                   $subnav_prev = $prev_nav_link.next('.page-nav__subnav');
261               if ($subnav_prev.length === 1) { // hide current subnav, show previous and select last element
262                  $subnav.attr({
263                     'data-visually-hidden': 'true'
264                  });
265                  $subnav_prev.attr({
266                    'data-visually-hidden': 'false'
267                  });
268                  $subnav_prev.find(" .page-nav__subnav__item:last-child ").children(".page-nav__subnav__link").focus();
269                  event.preventDefault();
270               }
271            }
272         }
273
274      });
275
276   // events on submenu item
277   $body.on('keydown', '.page-nav__subnav__link', function(event) {
278         var $this = $(this),
279             $subnav = $this.parents('.page-nav__subnav'),
280             $subnav_item = $this.parents('.page-nav__subnav__item'),
281             $nav_link = $subnav.prev('.page-nav__link'),
282             $nav_item = $nav_link.parents('.page-nav__item'),
283             $nav = $nav_link.parents('.page-nav');
284
285         // event keyboard bottom
286         if (event.keyCode == 40) {
287            // if we are on last => activate first
288            if ($subnav_item.is(".page-nav__subnav__item:last-child")) {
289               $subnav.find(".page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
290            }
291            // else activate next
292            else {
293               $subnav_item.next().children(".page-nav__subnav__link").focus();
294            }
295            event.preventDefault();
296         }
297         // event keyboard top
298         if (event.keyCode == 38) {
299            // if we are on first => activate last
300            if ($subnav_item.is(".page-nav__subnav__item:first-child")) {
301               $subnav.find(" .page-nav__subnav__item:last-child ").children(".page-nav__subnav__link").focus();
302            }
303            // else activate previous
304            else {
305               $subnav_item.prev().children(".page-nav__subnav__link").focus();
306            }
307            event.preventDefault();
308         }
309         // event keyboard Esc
310         if (event.keyCode == 27) {
311            // close the menu
312            $nav_link.focus();
313            $subnav.attr({
314               'data-visually-hidden': 'true'
315            });
316            event.preventDefault();
317         }
318         // event keyboard right
319         if (event.keyCode == 39) {
320            // select next nav-system__link
321            $subnav.attr({
322               'data-visually-hidden': 'true'
323            });
324
325            // if we are on last => activate first and choose first item
326            if ($nav_item.is(".page-nav__item:last-child")) {
327               $next = $nav.find(" .page-nav__item:first-child ").children(".page-nav__link");
328               $next.focus();
329               $subnav_next = $next.next('.page-nav__subnav');
330               if ($subnav_next.length === 1) {
331                  $subnav_next.find(" .page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
332               }
333            }
334            // else activate next
335            else {
336               $next = $nav_item.next().children(".page-nav__link");
337               $next.focus();
338               $subnav_next = $next.next('.page-nav__subnav');
339               if ($subnav_next.length === 1) {
340                  $subnav_next.find(" .page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
341               }
342            }
343            event.preventDefault();
344         }
345         // event keyboard left
346         if (event.keyCode == 37) {
347            // select prev nav-system__link
348            $subnav.attr({
349               'data-visually-hidden': 'true'
350            });
351
352            // if we are on first => activate last and choose first item
353            if ($nav_item.is(".page-nav__item:first-child")) {
354               $prev = $nav.find(" .page-nav__item:last-child ").children(".page-nav__link");
355               $prev.focus();
356               $subnav_prev = $prev.next('.page-nav__subnav');
357               if ($subnav_prev.length === 1) {
358                  $subnav_prev.find(".page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
359               }
360            }
361            // else activate prev
362            else {
363               $prev = $nav_item.prev().children(".page-nav__link");
364               $prev.focus();
365               $subnav_prev = $prev.next('.page-nav__subnav');
366               if ($subnav_prev.length === 1) {
367                  $subnav_prev.find(".page-nav__subnav__item:first-child ").children(".page-nav__subnav__link").focus();
368               }
369            }
370            event.preventDefault();
371         }
372         // event tab
373         if (event.keyCode == 9 && !event.shiftKey) { // if we are on last subnav of last item and we go forward => hide subnav
374            if ($nav_item.is(".page-nav__item:last-child") && $subnav_item.is(".page-nav__subnav__item:last-child")) {
375               $subnav.attr({
376                  'data-visually-hidden': 'true'
377               });
378            }
379         }
380
381      })
382     .on('focus', '.page-nav__subnav__link', function(event) {
383         var $this = $(this),
384             $subnav = $this.parents('.page-nav__subnav'),
385             $subnav_item = $this.parents('.page-nav__item'),
386             $nav_link = $subnav.prev('.page-nav__link'),
387             $nav_item = $nav_link.parents('.page-nav__item'),
388             $nav = $nav_link.parents('.page-nav__item'),
389             $subnavSub = $this.next('.page-nav__subnav'),
390             $subnavSub_item = $this.parents('.page-nav__subnav__item'),
391             $navSub_link = $subnav.prev('.page-nav__subnav__link'),
392             $navSub_item = $navSub_link.parents('.page-nav__subnav__item'),
393             $navSub = $navSub_link.parents('.page-nav__subnav__item');
394
395         $nav_item.attr({
396            'data-show-sub': 'true'
397         });
398
399         // $subnavSub_item.attr({
400         //    'data-show-sub': 'true'
401         // });
402
403         // $subnavSub_item.siblings().find('i').removeClass('fa-minus').addClass('fa-plus');
404         //
405         // $this.siblings('i').toggleClass('fa-minus fa-plus');
406
407         // hide other menus and show submenu activated
408         // $subnavSub_item.siblings().find('.page-nav__subnav').attr({
409         //    'data-visually-hidden': 'true'
410         // });
411
412
413          // hide other menus and show submenu activated
414          $this.parent('.page-nav__subnav__item').siblings().find('.page-nav__subnav').attr({
415            'data-visually-hidden': 'true'
416          });
417
418          $this.parent('.page-nav__subnav__item').siblings().removeClass('open');
419
420         if ($subnavSub.length === 1) {
421            $subnavSub.attr({
422               'data-visually-hidden': 'false'
423            });
424           $subnavSub_item.addClass('open');
425         }
426      })
427
428      .on('focus', '.page-nav__subnav__link_2', function(event) {
429         var $this = $(this),
430             $subnav = $this.parents('.page-nav__subnav'),
431             $subnav_item = $this.parents('.page-nav__item'),
432             $nav_link = $subnav.prev('.page-nav__link'),
433             $nav_item = $nav_link.parents('.page-nav__item'),
434             $nav = $nav_link.parents('.page-nav__item'),
435             $subnavSub = $this.next('.page-nav__subnav_2'),
436             $subnavSub_item = $this.parents('.page-nav__subnav__item'),
437             $navSub_link = $subnav.prev('.page-nav__subnav__link'),
438             $navSub_item = $navSub_link.parents('.page-nav__subnav__item'),
439             $navSub = $navSub_link.parents('.page-nav__subnav__item');
440
441         $nav_item.attr({
442            'data-show-sub': 'true'
443         });
444
445         // $subnavSub_item.attr({
446         //    'data-show-sub': 'true'
447         // });
448
449         // $subnavSub_item.siblings().find('i').removeClass('fa-minus').addClass('fa-plus');
450         //
451         // $this.siblings('i').toggleClass('fa-minus fa-plus');
452
453         // hide other menus and show submenu activated
454         // $subnavSub_item.siblings().find('.page-nav__subnav').attr({
455         //    'data-visually-hidden': 'true'
456         // });
457
458
459          // hide other menus and show submenu activated
460          $this.parent('.page-nav__subnav__item').siblings().find('.page-nav__subnav_2').attr({
461            'data-visually-hidden': 'true'
462          });
463
464         if ($subnavSub.length === 1) {
465            $subnavSub.attr({
466               'data-visually-hidden': 'false'
467            });
468         }
469      })
470      .on('focusout', '.page-nav__subnav__link', function(event) {
471         var $this = $(this),
472             $subnav = $this.parents('.page-nav__subnav'),
473             $subnav_item = $this.parents('.page-nav__subnav__item'),
474             $subnavSub_item = $this.parents('.page-nav__subnav__item'),
475             $nav_link = $subnav.prev('.page-nav__link'),
476             $nav_item = $nav_link.parents('.page-nav__item'),
477             $nav = $nav_link.parents('.page-nav__item');
478
479         $this.parent('.page-nav__subnav__item').siblings().removeClass('open');
480
481         $nav_item.attr({
482            'data-show-sub': 'false'
483         });
484      });
485
486      function enableNavSubHover(){
487        var desktopView = $(document).width();
488        if(desktopView >= "991"){
489      $body.on('mouseenter', '.full-width .page-nav__subnav__item', function(event) {
490            var $this = $(this),
491                $subnav_link = $this.children('.page-nav__subnav__link'),
492                $subnavSub_item = $this.parents('.page-nav__subnav__item'),
493                $subnav = $this.children('.page-nav__subnav');
494
495            $this.attr({
496               'data-show-sub': 'true'
497            });
498
499
500            // show submenu
501            if ($subnav.length === 1) {
502                $this.siblings().find('.page-nav__subnav').attr({
503                  'data-visually-hidden': 'true'
504                });
505               $this.siblings().removeClass('open');
506
507               $subnav.attr({
508                  'data-visually-hidden': 'false'
509               });
510
511                $this.addClass('open');
512            }
513
514         })
515         .on('mouseleave', '.full-width .page-nav__subnav__item', function(event) {
516            var $this = $(this),
517                $subnav_link = $this.children('.page-nav__subnav__link'),
518                $subnavSub_item = $this.parents('.page-nav__subnav__item'),
519                $subnav = $this.children('.page-nav__subnav');
520
521            $this.attr({
522               'data-show-sub': 'false'
523            });
524            // show submenu
525            if ($subnav.length === 1) {
526               // $subnav.attr({
527               //    'data-visually-hidden': 'true'
528               // });
529            }
530
531         });
532       }else{
533
534       }
535     }
536       //Run function on resize
537       enableNavHover();
538       enableNavSubHover()
539       $(window).on("resize", function(){
540           enableNavHover();
541           enableNavSubHover();
542       });
543
544});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.