1"use strict"; 2/** 3 * General Custom JS Functions 4 * 5 * @author Themovation <[email protected]> 6 * @copyright 2014 Themovation INC. 7 * @license http://themeforest.net/licenses/regular 8 * @version 1.3 9 */ 10 11/* 12 # Helper Functions 13 # On Window Resize 14 # On Window Load 15 */ 16 17//====================================================================== 18// Helper Functions 19//====================================================================== 20 21//----------------------------------------------------- 22// NAVIGATION - Adds support for Mobile Navigation 23// Detect screen size, add / subtract data-toggle 24// for mobile dropdown menu. 25//----------------------------------------------------- 26function themo_support_mobile_navigation() { 27 // If mobile navigation is active, add data attributes for mobile touch / toggle 28 if (Modernizr.mq("(max-width: 767px)")) { 29 //console.log('Adding data-toggle, data-target'); 30 jQuery("li.dropdown .dropdown-toggle").attr("data-toggle", "dropdown"); 31 jQuery("li.dropdown .dropdown-toggle").attr("data-target", "#"); 32 } 33 34 // If mobile navigation is NOT active, remove data attributes for mobile touch / toggle 35 if (Modernizr.mq("(min-width:768px)")) { 36 //console.log('Removing data-toggle, data-target'); 37 jQuery("li.dropdown .dropdown-toggle").removeAttr( 38 "data-toggle", 39 "dropdown" 40 ); 41 jQuery("li.dropdown .dropdown-toggle").removeAttr("data-target", "#"); 42 } 43} 44 45//----------------------------------------------------- 46// Detect if touch device via modernizr, return true 47//----------------------------------------------------- 48function themo_is_touch_device(checkScreenSize) { 49 if (typeof checkScreenSize === "undefined" || checkScreenSize === null) { 50 checkScreenSize = true; 51 } 52 53 var deviceAgent = navigator.userAgent.toLowerCase(); 54 55 var isTouch = 56 deviceAgent.match(/(iphone|ipod|ipad)/) || 57 deviceAgent.match(/(android)/) || 58 deviceAgent.match(/iphone/i) || 59 deviceAgent.match(/ipad/i) || 60 deviceAgent.match(/ipod/i) || 61 deviceAgent.match(/blackberry/i); 62 63 if (checkScreenSize) { 64 var isMobileSize = Modernizr.mq("(max-width:767px)"); 65 } else { 66 var isMobileSize = false; 67 } 68 69 if (isTouch || isMobileSize) { 70 return true; 71 } 72 73 return false; 74} 75 76//----------------------------------------------------- 77// Disable Transparent Header for Mobile 78//----------------------------------------------------- 79function themo_no_transparent_header_for_mobile(isTouch) { 80 if (jQuery(".navbar[data-transparent-header]").length) { 81 if (isTouch) { 82 jQuery(".navbar").attr("data-transparent-header", "false"); 83 } else { 84 jQuery(".navbar").attr("data-transparent-header", "true"); 85 } 86 } 87} 88 89//----------------------------------------------------- 90// Scroll Up 91//----------------------------------------------------- 92function themo_start_scrollup() { 93 jQuery.scrollUp({ 94 animationSpeed: 200, 95 animation: "fade", 96 scrollSpeed: 500, 97 scrollImg: { 98 active: true, 99 type: "background", 100 src: "../../images/top.png", 101 }, 102 }); 103} 104 105var nice = false; 106 107/** 108 * Protect window.console method calls, e.g. console is not defined on IE 109 * unless dev tools are open, and IE doesn't define console.debug 110 */ 111(function () { 112 //retinajs(); 113 114 if (!window.console) { 115 window.console = {}; 116 } 117 // union of Chrome, FF, IE, and Safari console methods 118 var m = [ 119 "log", 120 "info", 121 "warn", 122 "error", 123 "debug", 124 "trace", 125 "dir", 126 "group", 127 "groupCollapsed", 128 "groupEnd", 129 "time", 130 "timeEnd", 131 "profile", 132 "profileEnd", 133 "dirxml", 134 "assert", 135 "count", 136 "markTimeline", 137 "timeStamp", 138 "clear", 139 ]; 140 // define undefined methods as noops to prevent errors 141 for (var i = 0; i < m.length; i++) { 142 if (!window.console[m[i]]) { 143 window.console[m[i]] = function () {}; 144 } 145 } 146})(); 147 148//====================================================================== 149// Executes when HTML-Document is loaded and DOM is ready 150//====================================================================== 151jQuery(document).ready(function ($) { 152 "use strict"; 153 154 // Preloader : Is really only used for the flexslider but is added to the body tag. 155 // If flex is detected, we put a timeout on it (5s( so it does not get stuck spinning. 156 // If no flex, then disable. 157 if (jQuery("#main-flex-slider")[0]) {
158 // Do nothing / flex will figure it out. 159 setTimeout(function () { 160 jQuery("body").addClass("loaded"); 161 }, 10000); 162 } else { 163 jQuery("body").addClass("loaded"); 164 } 165 166 // add body class for touch devices. 167 if (themo_is_touch_device()) { 168 jQuery("body").addClass("th-touch"); 169 } 170 171 // Add support for mobile navigation 172 themo_support_mobile_navigation($); 173 174 // Support for sub menu navigation / also works with sticky header. 175 176 jQuery("body").on( 177 "click", 178 "ul.dropdown-menu .dropdown-submenu > a[data-toggle='dropdown']", 179 function (event) { 180 //console.log($(this).text()); 181 event.preventDefault(); 182 event.stopPropagation(); 183 jQuery(this) 184 .parents("ul.dropdown-menu .dropdown-submenu") 185 .toggleClass("open"); 186 } 187 ); 188 189 // Sticky Header - Set options 190 var options = { 191 // Scroll offset. Accepts Number or "String" (for class/ID) 192 offset: 125, // OR â offset: '.classToActivateAt', 193 194 classes: { 195 clone: "headhesive--clone", 196 stick: "headhesive--stick", 197 unstick: "headhesive--unstick", 198 }, 199 200 // If the top nav bar menu is open, close it. 201 onStick: function () { 202 //jQuery( "header:not('.headhesive--stick') .navbar-toggle").not( ".collapsed" ).trigger( "click" ); 203 jQuery(".navbar-collapse").css("height", "0"); 204 jQuery(".navbar-collapse").removeClass("in"); 205 }, 206 // If the top nav bar menu is open, close it. 207 onUnstick: function () { 208 //jQuery( "header:not('.headhesive--stick') .navbar-toggle").not( ".collapsed" ).trigger( "click" ); 209 jQuery(".navbar-collapse").css("height", "0"); 210 jQuery(".navbar-collapse").removeClass("in"); 211 }, 212 // Throttle scroll event to fire every 250ms to improve performace 213 throttle: 250, 214 }; 215 216 try { 217 // Initialise with options 218 var banner = new Headhesive( 219 "body.th-sticky-header .banner, body.ehf-header.th-sticky-header header#masthead", 220 options 221 ); 222 jQuery("body.th-sticky-header").addClass("headhesive"); 223 } catch (err) { 224 console.log( 225 "Sticky header deactivated. WP Dash / Appearance / Customize / Theme Options / Menu & Header" 226 ); 227 } 228 229 // Close sticky header on menu item click. 230 jQuery(".navbar-collapse").on( 231 "click", 232 "a:not(.dropdown-toggle)", 233 function () { 234 //jQuery( ".navbar-toggle").not( ".collapsed" ).trigger( "click" ); 235 jQuery(".navbar-collapse").css("height", "0"); 236 jQuery(".navbar-collapse").removeClass("in"); 237 } 238 ); 239 240 /** 241 * Check a href for an anchor. If exists, and in document, scroll to it. 242 * If href argument ommited, assumes context (this) is HTML Element, 243 * which will be the case when invoked by jQuery after an event 244 */ 245 function scroll_if_anchor(href) { 246 href = typeof href == "string" ? href : jQuery(this).attr("href"); 247 248 var fromTop = 0; 249 if (jQuery("header").hasClass("headhesive--clone")) { 250 fromTop = jQuery(".headhesive--clone").height(); 251 } 252 253 // You could easily calculate this dynamically if you prefer 254 //var fromTop = 50; 255 256 // If our Href points to a valid, non-empty anchor, and is on the same page (e.g. #foo) 257 // Legacy jQuery and IE7 may have issues: http://stackoverflow.com/q/1593174 258 if (href.indexOf("#") == 0) { 259 var $target = jQuery(href); 260 261 // Older browser without pushState might flicker here, as they momentarily 262 // jump to the wrong position (IE < 10) 263 if ($target.length) { 264 jQuery("html, body").animate( 265 { scrollTop: $target.offset().top - fromTop }, 266 500, 267 "linear", 268 function () { 269 //alert("Finished animating"); 270 } 271 ); 272 if (history && "pushState" in history) { 273 history.pushState( 274 {}, 275 document.title, 276 window.location.pathname + href 277 ); 278 return false; 279 } 280 } 281 } 282 } 283 284 // When our page loads, check to see if it contains and anchor 285 scroll_if_anchor(window.location.hash); 286 287 // Detect and set isTouch for touch screens 288 // var isTouch = themo_is_touch_device(); 289
290 // Set off set for waypoints 291 //if(!isTouch){ 292 //Setup waypoints plugin 293 294 var th_offset = 0; 295 if (jQuery("header").hasClass("headhesive--clone")) { 296 th_offset = jQuery(".headhesive--clone").height(); 297 } 298 299 // Add space for Elementor Menu Anchor link 300 jQuery(window).on("elementor/frontend/init", function () { 301 elementorFrontend.hooks.addFilter( 302 "frontend/handlers/menu_anchor/scroll_top_distance", 303 function (scrollTop) { 304 //console.log('ELEM HOOK - Scroll offset ' + th_offset); 305 return scrollTop - th_offset; 306 } 307 ); 308 }); 309 //} 310 311 if ( 312 navigator.userAgent.indexOf("Safari") != -1 && 313 navigator.userAgent.indexOf("Chrome") == -1 314 ) { 315 //console.log('Smooth Scroll Off (Safari).'); 316 } else { 317 try { 318 // Initialise with options 319 nice = jQuery("html").niceScroll({ 320 zindex: 20000, 321 scrollspeed: 60, 322 mousescrollstep: 60, 323 cursorborderradius: "10px", // Scroll cursor radius 324 cursorborder: "1px solid rgba(255, 255, 255, 0.4)", 325 cursorcolor: "rgba(0, 0, 0, 0.6)", // Scroll cursor color 326 //autohidemode: 'true', // Do not hide scrollbar when mouse out 327 cursorwidth: "10px", // Scroll cursor width 328 autohidemode: false, 329 }); 330 } catch (err) { 331 //console.log('Smooth Scroll Off.'); 332 } 333 } 334}); 335 336//====================================================================== 337// On Window Load - executes when complete page is fully loaded, including all frames, objects and images 338//====================================================================== 339jQuery(window).on("load", function ($) { 340 "use strict"; 341 342 // Detect and set isTouch for touch screens 343 var isTouch = themo_is_touch_device(); 344 345 // Disable Transparent Header for Mobile / touch 346 themo_no_transparent_header_for_mobile(isTouch); 347 348 // Start Scroll Up 349 themo_start_scrollup(); 350 351 if (wp_object.SEO_DEBUG) { 352 logSEO(); 353 } 354}); 355 356//====================================================================== 357// On Window Resize 358//====================================================================== 359jQuery(window).resize(function ($) { 360 "use strict"; 361 // Detect and set isTouch for touch screens 362 var isTouch = themo_is_touch_device(); 363 364 // Add support for mobile navigation 365 themo_support_mobile_navigation(); 366 367 // Disable Transparent Header for Mobile / touch 368 themo_no_transparent_header_for_mobile(isTouch); 369}); 370 371function logSEO() { 372 console.log("SEO Log enabled..."); 373 374 // Log CLS 375 let cls = 0; 376 new PerformanceObserver((entryList) => { 377 for (const entry of entryList.getEntries()) { 378 if (!entry.hadRecentInput) { 379 cls += entry.value; 380 console.log("Current CLS value:", cls, entry); 381 } 382 } 383 }).observe({ type: "layout-shift", buffered: true }); 384 385 // Log LCP 386 new PerformanceObserver((list) => { 387 const entries = list.getEntries(); 388 const lastEntry = entries[entries.length - 1]; 389 390 console.log("LCP element:", lastEntry.element); 391 }).observe({ type: "largest-contentful-paint", buffered: true }); 392 393 // Log FID 394 new PerformanceObserver((list) => { 395 const fidEntry = list.getEntries()[0]; 396 const navEntry = performance.getEntriesByType("navigation")[0]; 397 const wasFIDBeforeDCL = 398 fidEntry.startTime < navEntry.domContentLoadedEventStart; 399 400 console.log("FID occurred before DOMContentLoaded:", wasFIDBeforeDCL); 401 }).observe({ type: "first-input", buffered: true }); 402 403 // Log INP 404 function logINPDebugInfo(inpEntry) { 405 console.log("INP target element:", inpEntry.target); 406 console.log("INP interaction type:", inpEntry.name); 407 408 const navEntry = performance.getEntriesByType("navigation")[0]; 409 const wasINPBeforeDCL = 410 inpEntry.startTime < navEntry.domContentLoadedEventStart; 411 412 console.log("INP occurred before DCL:", wasINPBeforeDCL); 413 } 414}
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.