// Custom JavaScript for IT Learning Notes // Wait for the DOM to be fully loaded document.addEventListener('DOMContentLoaded', function() { // Improve anchor link scrolling behavior document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function(e) { e.preventDefault(); const targetId = this.getAttribute('href'); // Only process internal page links if (targetId.startsWith('#')) { const targetElement = document.querySelector(targetId); if (targetElement) { // Smooth scroll to the target window.scrollTo({ top: targetElement.offsetTop - 60, // Account for header/navigation behavior: 'smooth' }); // Update URL without reloading the page history.pushState(null, null, targetId); } } }); }); // Add "Back to Top" links if they don't exist in the content const sections = document.querySelectorAll('h2'); sections.forEach(section => { // Check if there's already a back-to-top link after this section const nextElement = section.nextElementSibling; const hasBackToTop = false; // Find the end of this section (next h2 or end of document) let currentElement = section.nextElementSibling; while (currentElement && currentElement.tagName !== 'H2') { if (currentElement.tagName === 'A' && currentElement.getAttribute('href') && currentElement.getAttribute('href').includes('top')) { hasBackToTop = true; break; } currentElement = currentElement.nextElementSibling; } // Add back-to-top link if needed if (!hasBackToTop && currentElement && currentElement.tagName === 'H2') { const backToTop = document.createElement('a'); backToTop.href = '#'; backToTop.textContent = 'Back to Top'; backToTop.className = 'back-to-top'; backToTop.style.display = 'block'; backToTop.style.marginBottom = '2em'; // Insert before the next heading section.parentNode.insertBefore(backToTop, currentElement); } }); // Fix for any dynamically loaded content setTimeout(function() { // Force redraw of content area const content = document.querySelector('.content'); if (content) { content.style.display = 'none'; content.offsetHeight; // Force reflow content.style.display = 'block'; } // Scroll to anchor if present in URL if (window.location.hash) { const element = document.getElementById(window.location.hash.substring(1)); if (element) { element.scrollIntoView({behavior: 'smooth'}); } } }, 100); }); // Create a table of contents if it doesn't exist function generateTableOfContents() { // Only run if we don't have a TOC div already if (!document.querySelector('.toc')) { const headings = document.querySelectorAll('h2'); if (headings.length > 2) { // Only if we have a reasonable number of headings const toc = document.createElement('div'); toc.className = 'toc'; const tocTitle = document.createElement('h2'); tocTitle.textContent = 'Table of Contents'; toc.appendChild(tocTitle); const tocList = document.createElement('ul'); headings.forEach(heading => { if (!heading.textContent.toLowerCase().includes('table of contents')) { const listItem = document.createElement('li'); const link = document.createElement('a'); // Create an id for the heading if it doesn't have one if (!heading.id) { heading.id = heading.textContent.toLowerCase() .replace(/[^\w]+/g, '-'); } link.href = '#' + heading.id; link.textContent = heading.textContent; listItem.appendChild(link); tocList.appendChild(listItem); } }); toc.appendChild(tocList); // Insert after the first heading (title) const title = document.querySelector('h1'); if (title && title.nextElementSibling) { title.parentNode.insertBefore(toc, title.nextElementSibling.nextElementSibling); } } } } // Run when the page loads window.addEventListener('load', function() { // Generate TOC if needed generateTableOfContents(); // Enable all sections that might have been hidden document.querySelectorAll('.content-hidden') .forEach(el => el.classList.remove('content-hidden')); }); // Monitor for any dynamically added elements and ensure they're visible const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { for (let i = 0; i < mutation.addedNodes.length; i++) { const node = mutation.addedNodes[i]; if (node.nodeType === 1) { // Element node if (node.classList && ( node.classList.contains('section') || node.classList.contains('content') || node.classList.contains('content-hidden') )) { node.style.display = 'block'; node.style.visibility = 'visible'; node.style.opacity = '1'; node.classList.remove('content-hidden'); } } } } }); }); // Start observing the document body for changes observer.observe(document.body, { childList: true, subtree: true });