1// mega menu js 2 3var menuElement = "[bt-mega] :not('.sub-menu')>.menu-item"; 4var mobileToggle = '[bt-mega] .fl-menu-mobile-toggle'; 5 6function megaMenuTitle(theText){ 7 8 //v2 thanks Zack Pyle for inspo 9 theText = theText.replace(/[^0-9a-z]/gi, ' ').trim().replace(" ","-").replace(/[^\w-]+/g,"-").replace("---","-").replace("--","-"); 10 return theText.toLowerCase(); 11} 12 13function isMegaMobile(){ 14 15 breakpoint = FLBuilderLayoutConfig.breakpoints.small 16 17 if(jQuery('.fl-menu-responsive-toggle-medium-mobile').length){ 18 breakpoint = FLBuilderLayoutConfig.breakpoints.medium; 19 } 20 21 if(jQuery('.fl-menu-responsive-toggle-always').length){ 22 return true; 23 } 24 25 var status = breakpoint > jQuery(window).width(); 26 27 return status; 28} 29 30 31function megaDebug(){ 32 jQuery(menuElement).each(function(){ 33 console.log("mega-"+megaMenuTitle(jQuery(this).text())); 34 }); 35} 36 37jQuery(document).ready(function(){ 38 39 // dont do if bb is running 40 if(jQuery('body').hasClass('fl-builder-edit')) 41 return true; 42 43 if(jQuery('[id^="mega-"]').length == 0) 44 return; 45 46 //add the helper parent class to the mega menu for mobile 47 jQuery('[id^="mega-"]').first().parent().addClass('mega-mobile-container'); 48 49 window.megaWidthCurrentScreenWidth = isMegaMobile(); // save current width to global 50 51 //set location of megas on resize 52 jQuery(window).on('resize', function () { 53 54 // refresh if screensize changes to from responsive 55 56 if(window.megaWidthCurrentScreenWidth !== isMegaMobile()){ 57 window.megaWidthCurrentScreenWidth = isMegaMobile(); 58 hideMega(); 59 } 60 61 if(isMegaMobile())// set init value 62 { 63 //set top value of container 64 topValue = jQuery('[bt-mega]')[0].getBoundingClientRect().bottom; 65 if(jQuery('#wpadminbar').length){ 66 topValue += jQuery('#wpadminbar')[0].getBoundingClientRect().bottom; 67 } 68 jQuery('.mega-mobile-container').css('top',topValue + 'px'); 69 } 70 else 71 { 72 topValue = 0; 73 jQuery('.mega-mobile-container').css('top',topValue); 74 jQuery('.show-mega-mobile').removeClass('show-mega-mobile'); 75 } 76 77 }).resize(); 78 79 jQuery(menuElement).each(function(){ 80 81 //get attrs about mega menu 82 var menuItem = jQuery(this); 83 var megaItem = jQuery("#"+"mega-"+megaMenuTitle(menuItem.text())); 84 var nextItem; 85 86 if(megaItem.length) // if its mega anything 87 { 88 megaMouse = menuItem.parents('[bt-mega-style]').attr('bt-mega-style'); 89 if(megaMouse == 'hover') 90 menuItem.addClass('has-mega-menu').addClass('hover-mega-menu'); 91 else 92 menuItem.addClass('has-mega-menu').addClass('click-mega-menu'); 93 94 menuItem.addClass('has-mega-menu').children('a').attr('aria-expanded', 'false').attr('role', 'button').append('<span class="fl-menu-toggle"></span>'); 95 96 //set up click listeners for menu items ################################################################################################################################################ 97 menuItem.children().on('mouseenter mousedown click focus',function(event) { 98 99 megaMouse = menuItem.parents('[bt-mega-style]').attr('bt-mega-style'); // get mega style 100 if(megaMouse == 'click') // prevent default click if its a click mega menu 101 { 102 event.preventDefault(); 103 event.stopPropagation(); 104 } 105 106 if(event.type == 'mousedown' && megaMouse == 'click') 107 return; 108 109 if(event.type == 'focus' && megaMouse == 'click') 110 return; 111 112 if(event.type == 'focus' && megaMouse == 'click') 113 return; 114 115 if (event.type == 'click' && megaMouse == 'click') { 116 mm = jQuery("#" + "mega-" + megaMenuTitle(jQuery(this).text())); 117 118 if (mm.hasClass('show-mega')) { 119 hideMega(); 120 return; 121 } 122 } 123 124 if(event.type == 'click' && megaMouse == 'click' && jQuery(this).attr('class') == 'meg-exit') // ignore clicks, unles its a focus click kinda hacky but no issues sofa 125 hideMega(); 126 127 if(event.type == 'click' && megaMouse == 'hover') // dont interfere with clicks on hover menus 128 return; 129 130 if(event.type == 'mouseenter' && megaMouse == 'click') // ignore hovers on click megas 131 return; 132 133 //pause a little to allow for the hide function to hide stuff 134 setTimeout(() => { //() => { fun method to pass 'this' 135 136 mm = jQuery("#mega-"+megaMenuTitle(jQuery(this).text())); 137 // if it has a mega menu 138 if(mm.length && !isMegaMobile()) 139 { 140 // ok we're ready to do the showing 141 if(!mm.hasClass('show-mega')) 142 { 143 hideMega();
144 megaSpeed = parseInt(jQuery('[bt-mega-animate-speed]').attr('bt-mega-animate-speed') || 0); // get mega style 145 mm.addClass('show-mega').animate({opacity: 1}, megaSpeed); // show it 146 jQuery("body").trigger( "mega-menu-open" ).addClass('showing-mega-menu'); 147 148 if(megaMouse == 'hover'){ 149 //add 150 mm.addClass('hover-mega-menu'); 151 menuItem.find('a').attr('tabindex',101); 152 // previous item add meg-exit 153 prevItem = menuItem; 154 foundPrev = false; 155 // get the next row with an a or button, but not if its a megas menu div 156 while(foundPrev == false){ 157 158 if( prevItem.prev().find('a:visible,button:visible').last().parents('.mega-mobile-container').length) 159 { 160 //console.log('its in a mega menu, ignorin'); 161 } 162 else if( (prevItem.prev().find('a:visible,button:visible').last().length) ) 163 { 164 foundPrev = true; 165 prevItem = prevItem.prev().find('a:visible,button:visible').last(); 166 } 167 168 // move the pointer 169 if(!foundPrev) 170 if(prevItem.prev().length) 171 prevItem = prevItem.prev(); 172 else 173 prevItem = prevItem.parent(); 174 175 } 176 prevItem.attr('tabindex',100).addClass('meg-exit'); 177 178 } 179 else 180 menuItem.find('a').attr('tabindex',100).addClass('meg-exit'); 181 182 menuItem.children('a').attr('aria-expanded', 'true');// ariaaaaal 183 184 mm.find('a, button, input, select, textarea').attr('tabindex',101); 185 186 nextItem = menuItem; 187 foundNext = false; 188 // get the next row with an a or button, but not if its a megas menu div 189 while(foundNext == false){ 190 191 if( nextItem.next().find('a:visible,button:visible').first().parents('.mega-mobile-container').length) 192 { 193 //its in a mega menu, ignorin 194 } 195 else if( (nextItem.next().find('a:visible,button:visible').first().length) ) 196 { 197 foundNext = true; 198 nextItem = nextItem.next().find('a:visible,button:visible').first(); 199 } 200 // move the pointer 201 if(!foundNext) 202 if(nextItem.next().length) 203 nextItem = nextItem.next(); 204 else 205 nextItem = nextItem.parent(); 206 207 } 208 nextItem.attr('tabindex',102).addClass('meg-exit'); 209 210 211 if(menuItem.parents('[bt-mega]').attr('bt-mega-position') == 'absolute') 212 { 213 mm.addClass('mega-absolute'); 214 } 215 216 jQuery(window).trigger('resize'); // for other code to resize themselves on show 217 } 218 } 219 220 },20); 221 }); 222 223 if(megaMouse == 'hover' ) 224 { 225 menuItem.addClass('mega-hover'); 226 227 menuItem.on('mouseleave',function(event) { 228 229 if (jQuery('.mega-mobile-container:hover, .mega-hover:hover').length == 0) 230 231 hideMega(); 232 233 }); 234 } 235 236 237 238 239 if(isMegaMobile()) 240 { 241 megaItem.css('top', topValue + 'px'); 242 topValue += megaItem.height(); 243 } 244 else 245 { 246 jQuery('body').removeClass('show-mega-mobile'); 247 topValue = menuItem.children()[0].getBoundingClientRect().bottom; 248 if(jQuery('#wpadminbar').length) 249 topValue = topValue + jQuery("#wpadminbar").height(); 250 megaItem.css('top', topValue + 'px'); 251 } 252 } 253 254 });
255 256 jQuery(mobileToggle).on('click',function(event){ 257 event.preventDefault(); // stop the inbuilt stuff from stuffin 258 event.stopPropagation(); 259 jQuery('body').toggleClass('show-mega-mobile'); 260 setTimeout(function(){ 261 jQuery(window).trigger('resize'); 262 },100); 263 }); 264 265 //close mega menu stuff 266 267 // on mouseleave of hover megas 268 jQuery('body').on('mouseleave','.hover-mega-menu',function(event) { 269 if (jQuery('.mega-hover:hover, .mega-mobile-container:hover ').length == 0) 270 hideMega(); 271 }); 272 273 jQuery('.has-mega-menu a').on('keypress', function (e) { // if space bar on button click it 274 if (e.keyCode === 32) { // if space 275 e.preventDefault(); 276 jQuery(this).click(); // click it 277 } 278 }); 279 280 // accessibility tab out of mega 281 jQuery('body').on('focus','.meg-exit',function(){ 282 hideMega(); 283 }); 284 285 // escape click 286 jQuery(document).on('keyup', function(e) { 287 if (e.key == "Escape" && jQuery('.showing-mega-menu').length) 288 { 289 var returnFocus = jQuery(menuElement + ".focus").find('a,button').first(); 290 // focus on parent 291 setTimeout(function(){ 292 returnFocus.focus(); 293 hideMega(); 294 },10); 295 } 296 }); 297 298 jQuery(document).on('click', function (e) { 299 300 //click outside of mega menu 301 if (jQuery(e.target).closest('[id^="mega-"], .mega-mobile-container').length === 0) { 302 if(jQuery('body').hasClass('showing-mega-menu')) 303 hideMega(); 304 } 305 else 306 { 307 if (jQuery(this).attr('href')) 308 { 309 var anchor = jQuery(this).attr('href').split('#').pop(); 310 if (jQuery("#"+anchor).length && jQuery('body').hasClass('showing-mega-menu')) 311 hideMega(); 312 } 313 } 314 315 }); 316 317 setInterval(() => { 318 if (scrolling) { 319 scrolling = false; 320 // place the scroll handling logic here 321 jQuery(window).trigger('resize'); 322 } 323/* 324 if(!isMegaMobile()) 325 { 326 jQuery('body').removeClass('show-mega-mobile'); 327 if (!jQuery('.mega-absolute').length) 328 { 329 if(jQuery(".mega-hover, .has-mega-menu").length) 330 { 331 topValue = jQuery(".mega-hover, .has-mega-menu").first()[0].getBoundingClientRect(); 332 jQuery("[id*='mega-']").css('top', topValue.bottom + 'px'); 333 } 334 } 335 } */ 336 },300); 337 338}); 339 340// scroll handler 341let scrolling = false; 342 343window.scroll = () => { 344 scrolling = true; 345}; 346 347function hideMega(){ 348 // dont do anything if theres nothing to do 349// if(!jQuery('.showing-mega-menu').length) 350 // return; 351 352 jQuery('.has-mega-menu [aria-expanded="true"]').attr('aria-expanded','false'); 353 jQuery('.mega-touched').removeClass('mega-touched'); 354 jQuery('.show-mega').css('opacity', 0).removeClass('show-mega'); 355 jQuery('.mega-hover').removeClass('mega-hover'); 356 jQuery('body').removeClass('show-mega-mobile').removeClass('showing-mega-menu'); 357 358 jQuery('[id^="mega-"] a, [bt-mega] a, .meg-exit').removeAttr('tabindex'); //kill tabindex on mega 359 jQuery('.meg-exit').removeClass('meg-exit'); 360}
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.