UNPKG

ultimate-jekyll-manager

Version:
147 lines (128 loc) 4.55 kB
// Classy Theme JavaScript // Modern interactions and animations (function() { 'use strict'; // Navbar shrink on scroll const navbar = document.querySelector('.navbar-modern'); if (navbar) { window.addEventListener('scroll', function() { if (window.scrollY > 50) { navbar.classList.add('navbar-scrolled'); } else { navbar.classList.remove('navbar-scrolled'); } }); } // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function(e) { const href = this.getAttribute('href'); if (href !== '#' && href !== '#!') { e.preventDefault(); const target = document.querySelector(href); if (target) { const navbarHeight = navbar ? navbar.offsetHeight : 0; const targetPosition = target.getBoundingClientRect().top + window.pageYOffset - navbarHeight - 20; window.scrollTo({ top: targetPosition, behavior: 'smooth' }); } } }); }); // Animate elements on scroll const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('animated'); observer.unobserve(entry.target); } }); }, observerOptions); // Observe all elements with animate-in class document.querySelectorAll('.animate-in').forEach(el => { observer.observe(el); }); // Add ripple effect to buttons document.querySelectorAll('.btn').forEach(button => { button.addEventListener('click', function(e) { const ripple = document.createElement('span'); const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.width = ripple.style.height = size + 'px'; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; ripple.classList.add('ripple'); this.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); }); // Parallax effect for hero sections const heroSections = document.querySelectorAll('.hero-section'); if (heroSections.length > 0) { window.addEventListener('scroll', () => { const scrolled = window.pageYOffset; heroSections.forEach(hero => { const rate = scrolled * -0.5; hero.style.transform = `translateY(${rate}px)`; }); }); } // Typing effect for headings with data-typing attribute const typingElements = document.querySelectorAll('[data-typing]'); typingElements.forEach(element => { const text = element.textContent; element.textContent = ''; element.style.visibility = 'visible'; let charIndex = 0; const typeInterval = setInterval(() => { if (charIndex < text.length) { element.textContent += text.charAt(charIndex); charIndex++; } else { clearInterval(typeInterval); } }, 50); }); // Enhanced tooltips initialization const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); tooltipTriggerList.forEach(tooltipTriggerEl => { new bootstrap.Tooltip(tooltipTriggerEl, { animation: true, delay: { show: 100, hide: 100 } }); }); // Form validation with modern styling const forms = document.querySelectorAll('.needs-validation'); forms.forEach(form => { form.addEventListener('submit', event => { if (!form.checkValidity()) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }, false); }); // Dynamic theme switching support const themeToggle = document.querySelector('[data-bs-theme-toggle]'); if (themeToggle) { themeToggle.addEventListener('click', () => { const currentTheme = document.documentElement.getAttribute('data-bs-theme') || 'light'; const newTheme = currentTheme === 'light' ? 'dark' : 'light'; document.documentElement.setAttribute('data-bs-theme', newTheme); localStorage.setItem('theme', newTheme); }); // Load saved theme const savedTheme = localStorage.getItem('theme') || 'light'; document.documentElement.setAttribute('data-bs-theme', savedTheme); } })();