1/** 2 * Accessible navigation 3 * 4 * @link http://a11yproject.com/ 5 * @link https://codeable.io/community/wordpress-accessibility-creating-accessible-dropdown-menus/ 6 * 7 * @package Reykjavik 8 * @copyright WebMan Design, Oliver Juhas 9 * 10 * @since 1.0.0 11 * @version 2.0.4 12 */ 13 14 15 16 17 18( function( $ ) { 19 20 'use strict'; 21 22 23 24 25 26 /** 27 * Helper variables 28 */ 29 30 var 31 $siteNavigation = $( document.getElementById( 'site-navigation' ) ), 32 $breakpoints = ( 'undefined' !== typeof $reykjavikBreakpoints ) ? ( $reykjavikBreakpoints ) : ( { 'l' : 880 } ); 33 34 35 36 /** 37 * Adding ARIA attributes 38 */ 39 40 $siteNavigation 41 .find( '.menu-item-has-children' ) 42 .attr( 'aria-haspopup', 'true' ); 43 44 45 46 /** 47 * Setting `.focus` class for menu parent 48 */ 49 50 $siteNavigation 51 .on( 'focus.aria mouseenter.aria', '.menu-item-has-children', function( e ) { 52 53 // Processing 54 55 $( e.currentTarget ) 56 .addClass( 'focus' ); 57 58 } ); 59 60 $siteNavigation 61 .on( 'blur.aria mouseleave.aria', '.menu-item-has-children', function( e ) { 62 63 // Processing 64 65 $( e.currentTarget ) 66 .removeClass( 'focus' ); 67 68 } ); 69 70 71 72 /** 73 * Touch-enabled 74 */ 75 76 $siteNavigation 77 .on( 'touchstart', '.menu-item-has-children > a', function( e ) { 78 79 // Requirements check 80 81 if ( parseInt( $breakpoints['l'] ) >= window.innerWidth ) { 82 return; 83 } 84 85 86 // Helper variables 87 88 var 89 el = $( this ).parent( 'li' ); 90 91 92 // Processing 93 94 /** 95 * First touch does not trigger the link, only opens the submenu. 96 * Second touch does trigger the link. 97 */ 98 if ( ! el.hasClass( 'focus' ) ) { 99 e.preventDefault(); 100 101 el 102 .toggleClass( 'focus' ) 103 .siblings( '.focus' ) 104 .removeClass( 'focus' ); 105 } 106 107 } ); 108 109 110 111 /** 112 * Menu navigation with arrow keys 113 */ 114 115 $siteNavigation 116 .on( 'keydown', 'a', function( e ) { 117 118 // Helper variables 119 120 var 121 $this = $( this ); 122 123 124 // Processing 125 126 if ( e.which === 37 ) { 127 128 // Left key 129 130 e.preventDefault(); 131 132 $this 133 .parent() 134 .prev() 135 .children( 'a' ) 136 .focus(); 137 138 } else if ( e.which === 39 ) { 139 140 // Right key 141 142 e.preventDefault(); 143 144 $this 145 .parent() 146 .next() 147 .children( 'a' ) 148 .focus(); 149 150 } else if ( e.which === 40 ) { 151 152 // Down key 153 154 e.preventDefault(); 155 156 if ( $this.next().length ) { 157 158 $this 159 .next() 160 .find( 'li:first-child a' ) 161 .first() 162 .focus(); 163 164 } else { 165 166 $this 167 .parent() 168 .next() 169 .children( 'a' ) 170 .focus(); 171 172 } 173 174 } else if ( e.which === 38 ) { 175 176 // Up key 177 178 e.preventDefault(); 179 180 if ( $this.parent().prev().length ) { 181 182 $this 183 .parent() 184 .prev() 185 .children( 'a' ) 186 .focus(); 187 188 } else { 189 190 $this 191 .parents( 'ul' ) 192 .first() 193 .prev( 'a' ) 194 .focus(); 195 196 } 197 198 } 199 200 } ); 201 202 203 204 205 206} )( jQuery );
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.