- CGV page: added trilingual content (FR/EN/MG) using data-lang-block divs - main.js: added data-lang-block toggle handler in applyLanguage() - translations.js: added cgv.heroTitle/heroSubtitle for FR/EN/MG - translations.js: fixed Malagasy (Fandefasana, Sarany), English (from Europe) - translations.js: added delivery delay precision (depuis le dépôt Paris) - translations.js: added 50+ missing i18n keys for tarifs/contact/guide/app/home - All footer CGV links updated with data-i18n attributes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
158 lines
4.5 KiB
JavaScript
158 lines
4.5 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const lang = localStorage.getItem('mva-lang') || 'fr';
|
|
applyLanguage(lang);
|
|
setupNav();
|
|
setupScrollEffects();
|
|
setupAnimations();
|
|
setupFAQ();
|
|
setActiveNavLink();
|
|
});
|
|
|
|
function applyLanguage(lang) {
|
|
document.documentElement.lang = lang;
|
|
localStorage.setItem('mva-lang', lang);
|
|
|
|
document.querySelectorAll('.lang-switcher button').forEach(btn => {
|
|
btn.classList.toggle('active', btn.dataset.lang === lang);
|
|
});
|
|
|
|
const t = translations[lang];
|
|
if (!t) return;
|
|
|
|
document.querySelectorAll('[data-i18n]').forEach(el => {
|
|
const keys = el.dataset.i18n.split('.');
|
|
let val = t;
|
|
for (const k of keys) {
|
|
val = val?.[k];
|
|
}
|
|
if (val !== undefined && val !== null) {
|
|
el.textContent = val;
|
|
}
|
|
});
|
|
|
|
document.querySelectorAll('[data-i18n-html]').forEach(el => {
|
|
const keys = el.dataset.i18nHtml.split('.');
|
|
let val = t;
|
|
for (const k of keys) {
|
|
val = val?.[k];
|
|
}
|
|
if (val !== undefined && val !== null) {
|
|
el.innerHTML = val.replace(/\n/g, '<br>');
|
|
}
|
|
});
|
|
|
|
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
|
|
const keys = el.dataset.i18nPlaceholder.split('.');
|
|
let val = t;
|
|
for (const k of keys) {
|
|
val = val?.[k];
|
|
}
|
|
if (val !== undefined && val !== null) {
|
|
el.placeholder = val;
|
|
}
|
|
});
|
|
|
|
// Blocs de contenu long par langue (ex: page CGV)
|
|
document.querySelectorAll('[data-lang-block]').forEach(el => {
|
|
el.style.display = el.dataset.langBlock === lang ? '' : 'none';
|
|
});
|
|
}
|
|
|
|
function setupNav() {
|
|
document.querySelectorAll('.lang-switcher button').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
applyLanguage(btn.dataset.lang);
|
|
});
|
|
});
|
|
|
|
const menuToggle = document.getElementById('menuToggle');
|
|
const mobileNav = document.getElementById('mobileNav');
|
|
const overlay = document.getElementById('overlay');
|
|
|
|
if (menuToggle && mobileNav) {
|
|
menuToggle.addEventListener('click', () => {
|
|
menuToggle.classList.toggle('open');
|
|
mobileNav.classList.toggle('open');
|
|
overlay?.classList.toggle('open');
|
|
document.body.style.overflow = mobileNav.classList.contains('open') ? 'hidden' : '';
|
|
});
|
|
|
|
overlay?.addEventListener('click', () => {
|
|
menuToggle.classList.remove('open');
|
|
mobileNav.classList.remove('open');
|
|
overlay.classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
});
|
|
|
|
mobileNav.querySelectorAll('a').forEach(link => {
|
|
link.addEventListener('click', () => {
|
|
menuToggle.classList.remove('open');
|
|
mobileNav.classList.remove('open');
|
|
overlay?.classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function setupScrollEffects() {
|
|
const header = document.querySelector('.header');
|
|
if (!header) return;
|
|
|
|
let lastScroll = 0;
|
|
window.addEventListener('scroll', () => {
|
|
const scrollY = window.scrollY;
|
|
header.classList.toggle('scrolled', scrollY > 50);
|
|
lastScroll = scrollY;
|
|
}, { passive: true });
|
|
}
|
|
|
|
function setupAnimations() {
|
|
const elements = document.querySelectorAll('.animate-on-scroll');
|
|
if (!elements.length) return;
|
|
|
|
const observer = new IntersectionObserver((entries) => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add('visible');
|
|
observer.unobserve(entry.target);
|
|
}
|
|
});
|
|
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
|
|
|
elements.forEach(el => observer.observe(el));
|
|
}
|
|
|
|
function setupFAQ() {
|
|
document.querySelectorAll('.faq-question').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
const item = btn.closest('.faq-item');
|
|
const answer = item.querySelector('.faq-answer');
|
|
const isOpen = item.classList.contains('open');
|
|
|
|
document.querySelectorAll('.faq-item.open').forEach(openItem => {
|
|
openItem.classList.remove('open');
|
|
openItem.querySelector('.faq-answer').style.maxHeight = '0';
|
|
});
|
|
|
|
if (!isOpen) {
|
|
item.classList.add('open');
|
|
answer.style.maxHeight = answer.scrollHeight + 'px';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function setActiveNavLink() {
|
|
const path = window.location.pathname;
|
|
const filename = path.split('/').pop() || 'index.html';
|
|
|
|
document.querySelectorAll('.nav a, .mobile-nav a').forEach(link => {
|
|
const href = link.getAttribute('href');
|
|
if (href === filename || (filename === '' && href === 'index.html')) {
|
|
link.classList.add('active');
|
|
link.setAttribute('aria-current', 'page');
|
|
}
|
|
});
|
|
}
|