113 lines
3.2 KiB
JavaScript
113 lines
3.2 KiB
JavaScript
/* ============================================
|
||
CEY Begeleiding – JavaScript
|
||
============================================ */
|
||
|
||
// Mobile Navigation Toggle
|
||
const navToggle = document.getElementById('navToggle');
|
||
const mainNav = document.getElementById('mainNav');
|
||
|
||
if (navToggle && mainNav) {
|
||
navToggle.addEventListener('click', () => {
|
||
const isOpen = navToggle.classList.toggle('active');
|
||
mainNav.classList.toggle('active');
|
||
navToggle.setAttribute('aria-expanded', String(isOpen));
|
||
});
|
||
|
||
// Close nav on link click
|
||
mainNav.querySelectorAll('.nav__link').forEach(link => {
|
||
link.addEventListener('click', () => {
|
||
navToggle.classList.remove('active');
|
||
mainNav.classList.remove('active');
|
||
navToggle.setAttribute('aria-expanded', 'false');
|
||
});
|
||
});
|
||
}
|
||
|
||
// Header scroll effect
|
||
const header = document.getElementById('header');
|
||
|
||
if (header) {
|
||
let lastScroll = 0;
|
||
window.addEventListener('scroll', () => {
|
||
const currentScroll = window.scrollY;
|
||
header.classList.toggle('header--scrolled', currentScroll > 20);
|
||
lastScroll = currentScroll;
|
||
}, { passive: true });
|
||
}
|
||
|
||
// Scroll animations (Intersection Observer)
|
||
const animateElements = document.querySelectorAll('[data-animate]');
|
||
|
||
if (animateElements.length > 0) {
|
||
const observerOptions = {
|
||
root: null,
|
||
rootMargin: '0px 0px -60px 0px',
|
||
threshold: 0.15
|
||
};
|
||
|
||
const observer = new IntersectionObserver((entries) => {
|
||
entries.forEach((entry, index) => {
|
||
if (entry.isIntersecting) {
|
||
// Stagger animation for siblings
|
||
const parent = entry.target.parentElement;
|
||
const siblings = parent ? parent.querySelectorAll('[data-animate]') : [];
|
||
let delay = 0;
|
||
|
||
if (siblings.length > 1) {
|
||
const siblingIndex = Array.from(siblings).indexOf(entry.target);
|
||
delay = siblingIndex * 100;
|
||
}
|
||
|
||
setTimeout(() => {
|
||
entry.target.classList.add('is-visible');
|
||
}, delay);
|
||
|
||
observer.unobserve(entry.target);
|
||
}
|
||
});
|
||
}, observerOptions);
|
||
|
||
animateElements.forEach(el => observer.observe(el));
|
||
}
|
||
|
||
// Smooth scroll for anchor links
|
||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||
anchor.addEventListener('click', function (e) {
|
||
const targetId = this.getAttribute('href');
|
||
if (targetId === '#') return;
|
||
|
||
const target = document.querySelector(targetId);
|
||
if (target) {
|
||
e.preventDefault();
|
||
target.scrollIntoView({
|
||
behavior: 'smooth',
|
||
block: 'start'
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
// Active nav link highlighting
|
||
const sections = document.querySelectorAll('section[id]');
|
||
const navLinks = document.querySelectorAll('.nav__link');
|
||
|
||
if (sections.length > 0 && navLinks.length > 0) {
|
||
const sectionObserver = new IntersectionObserver((entries) => {
|
||
entries.forEach(entry => {
|
||
if (entry.isIntersecting) {
|
||
const id = entry.target.getAttribute('id');
|
||
navLinks.forEach(link => {
|
||
link.classList.toggle('nav__link--active',
|
||
link.getAttribute('href') === `#${id}`
|
||
);
|
||
});
|
||
}
|
||
});
|
||
}, {
|
||
rootMargin: '-20% 0px -70% 0px',
|
||
threshold: 0
|
||
});
|
||
|
||
sections.forEach(section => sectionObserver.observe(section));
|
||
}
|