Files
it-knowledge/custom.js
T

164 lines
6.3 KiB
JavaScript

// 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
});