|
20 | 20 | <!-- Critical JavaScript - Load via CDN with proper fallback --> |
21 | 21 | <script> |
22 | 22 | (function() { |
| 23 | + // Queue for callbacks waiting for jQuery |
| 24 | + window._jqReady = []; |
| 25 | + window.jqReady = function(fn) { |
| 26 | + if (window.jQuery) fn(); |
| 27 | + else window._jqReady.push(fn); |
| 28 | + }; |
| 29 | + |
23 | 30 | var jq = document.createElement('script'); |
24 | 31 | jq.src = 'https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js'; |
25 | 32 | jq.integrity = 'sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8='; |
26 | 33 | jq.crossOrigin = 'anonymous'; |
27 | | - jq.onerror = function() { |
28 | | - var fallback = document.createElement('script'); |
29 | | - fallback.src = '{{ "/js/jquery.min.js" | prepend: site.baseurl }}'; |
30 | | - document.head.appendChild(fallback); |
31 | | - }; |
32 | | - document.head.appendChild(jq); |
33 | | -})(); |
34 | | -</script> |
35 | | - |
36 | | -<!-- Critical: Language Toggle Event Delegation (Must load before user interaction) --> |
37 | | -<script> |
38 | | - // Bind language toggle immediately after jQuery loads |
39 | | - // This prevents race conditions with async script loading |
40 | | - $(document).ready(function() { |
| 34 | + jq.onload = function() { |
| 35 | + // Execute queued callbacks |
| 36 | + window._jqReady.forEach(function(fn) { fn(); }); |
| 37 | + window._jqReady = []; |
| 38 | + // Language toggle |
41 | 39 | $(document).on('click', '.lang-btn[data-lang]', function(e) { |
42 | 40 | e.preventDefault(); |
43 | 41 | var lang = $(this).data('lang'); |
44 | | - |
45 | | - // If switchLanguage is already defined, use it |
46 | 42 | if (typeof window.switchLanguage === 'function') { |
47 | 43 | window.switchLanguage(lang); |
48 | | - } else { |
49 | | - // Otherwise, store the click and wait for the script to load |
50 | | - console.log('Language switch requested:', lang, '- waiting for script to load...'); |
51 | | - var checkInterval = setInterval(function() { |
52 | | - if (typeof window.switchLanguage === 'function') { |
53 | | - clearInterval(checkInterval); |
54 | | - window.switchLanguage(lang); |
55 | | - console.log('Script loaded, switching language to:', lang); |
56 | | - } |
57 | | - }, 100); // Check every 100ms |
58 | | - |
59 | | - // Timeout after 5 seconds |
60 | | - setTimeout(function() { |
61 | | - clearInterval(checkInterval); |
62 | | - }, 5000); |
63 | 44 | } |
64 | 45 | }); |
65 | | - }); |
| 46 | + }; |
| 47 | + jq.onerror = function() { |
| 48 | + var fallback = document.createElement('script'); |
| 49 | + fallback.src = '{{ "/js/jquery.min.js" | prepend: site.baseurl }}'; |
| 50 | + fallback.onload = jq.onload; |
| 51 | + document.head.appendChild(fallback); |
| 52 | + }; |
| 53 | + document.head.appendChild(jq); |
| 54 | +})(); |
66 | 55 | </script> |
67 | 56 |
|
68 | 57 | <!-- Non-Critical JavaScript - Load Asynchronously --> |
|
265 | 254 | {% if page.plchart %} |
266 | 255 | <!-- jquery.tagcloud.js --> |
267 | 256 | <script> |
268 | | - // https://stackoverflow.com/questions/9975810/make-iframe-automatically-adjust-height-according-to-the-contents-without-using |
269 | 257 | function resizeIframe(obj) { |
270 | 258 | obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px'; |
271 | 259 | } |
272 | 260 |
|
273 | | - $(document).ready(function () { |
| 261 | + jqReady(function () { |
274 | 262 | var $chart = document.querySelector("#chart"); |
275 | | - $chart.onload = function () { |
276 | | - resizeIframe($chart) |
| 263 | + if ($chart) { |
| 264 | + $chart.onload = function () { resizeIframe($chart); }; |
| 265 | + window.addEventListener("resize", function() { resizeIframe($chart); }); |
277 | 266 | } |
278 | | - window.addEventListener("resize", () => { |
279 | | - resizeIframe($chart) |
280 | | - }); |
281 | | - }) |
| 267 | + }); |
282 | 268 | </script> |
283 | 269 | {% endif %} |
284 | 270 |
|
|
472 | 458 | } |
473 | 459 | } |
474 | 460 |
|
475 | | - $(document).ready(function () { |
| 461 | + jqReady(function () { |
476 | 462 | var $searchPage = $('.search-page'); |
477 | 463 | var $searchOpen = $('.search-icon'); |
478 | 464 | var $searchClose = $('.search-icon-close'); |
|
491 | 477 | $searchClose.on('click', function (e) { |
492 | 478 | e.preventDefault(); |
493 | 479 | $searchPage.removeClass('search-active'); |
494 | | - $body.attr('class', prevClasses); // from closure |
| 480 | + $body.attr('class', prevClasses); |
495 | 481 | }); |
496 | 482 | $searchInput.focus(); |
497 | 483 | } |
|
0 commit comments