Portfolio avec Docker
This commit is contained in:
130
script.js
Normal file
130
script.js
Normal file
@@ -0,0 +1,130 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// ===============================================
|
||||
// 0. GESTION DU PRÉCHARGEUR (SPLASH SCREEN)
|
||||
// ===============================================
|
||||
|
||||
const preloader = document.getElementById('preloader');
|
||||
// const introSound = document.getElementById('soundToggle'); <-- Supprimé, car cette variable est trompeuse ici
|
||||
|
||||
if (preloader) {
|
||||
|
||||
// 1. Jouer le son de l'animation d'introduction
|
||||
// LIGNE(S) RETIRÉE(S) :
|
||||
/*
|
||||
if (introSound) {
|
||||
// Tenter de jouer le son immédiatement (les navigateurs peuvent le bloquer)
|
||||
introSound.play().catch(e => console.log("Intro sound blocked by browser:", e));
|
||||
}
|
||||
*/
|
||||
// Le son ne se jouera plus ici, mais seulement au clic sur le bouton de thème.
|
||||
|
||||
// 2. Définir le délai de 2000 ms (2 secondes) avant la disparition
|
||||
setTimeout(() => {
|
||||
// Retirer la classe active pour déclencher la transition CSS de disparition (opacité: 1 -> 0)
|
||||
preloader.classList.remove('preloader-active');
|
||||
|
||||
// 3. Suppression totale du DOM après la transition de 0.5 seconde
|
||||
setTimeout(() => {
|
||||
preloader.style.display = 'none';
|
||||
}, 500);
|
||||
|
||||
}, 2000); // Durée de l'animation principale avant le fade out
|
||||
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// 1. GESTION DU MODE SOMBRE (DARK MODE)
|
||||
// ===============================================
|
||||
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
const body = document.body;
|
||||
const localStorageKey = 'themePreference';
|
||||
|
||||
/**
|
||||
* Applique la classe .dark-mode au corps et met à jour le texte du bouton.
|
||||
* @param {boolean} isDarkMode - Vrai si le mode sombre doit être activé.
|
||||
*/
|
||||
function applyTheme(isDarkMode) {
|
||||
if (isDarkMode) {
|
||||
body.classList.add('dark-mode');
|
||||
themeToggle.textContent = 'Light mode';
|
||||
themeToggle.classList.remove('btn-outline-light');
|
||||
themeToggle.classList.add('btn-outline-warning');
|
||||
} else {
|
||||
body.classList.remove('dark-mode');
|
||||
themeToggle.textContent = 'Dark mode';
|
||||
themeToggle.classList.remove('btn-outline-warning');
|
||||
themeToggle.classList.add('btn-outline-light');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge le thème préféré depuis le localStorage ou détecte la préférence système.
|
||||
*/
|
||||
function loadTheme() {
|
||||
const storedTheme = localStorage.getItem(localStorageKey);
|
||||
let isDarkMode = false;
|
||||
|
||||
if (storedTheme !== null) {
|
||||
isDarkMode = storedTheme === 'dark';
|
||||
} else {
|
||||
isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
applyTheme(isDarkMode);
|
||||
}
|
||||
|
||||
// Charger le thème au chargement initial de la page
|
||||
if (themeToggle) {
|
||||
loadTheme();
|
||||
}
|
||||
|
||||
|
||||
// Événement au clic du bouton
|
||||
if (themeToggle) {
|
||||
themeToggle.addEventListener('click', () => {
|
||||
const isCurrentlyDark = body.classList.contains('dark-mode');
|
||||
const newTheme = isCurrentlyDark ? 'light' : 'dark';
|
||||
|
||||
// 1. Basculer le thème
|
||||
applyTheme(!isCurrentlyDark);
|
||||
|
||||
// 2. Stocker le nouveau choix
|
||||
localStorage.setItem(localStorageKey, newTheme);
|
||||
|
||||
// 3. (Optionnel) Jouer le son si l'élément audio existe
|
||||
const soundToggle = document.getElementById('soundToggle');
|
||||
if (soundToggle) {
|
||||
// C'est l'endroit CORRECT pour jouer le son (uniquement au clic)
|
||||
soundToggle.currentTime = 0;
|
||||
soundToggle.play().catch(e => console.log("Audio play failed:", e));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// 2. VALIDATION DES FORMULAIRES BOOTSTRAP
|
||||
// ===============================================
|
||||
|
||||
// Fonction d'auto-exécution pour la validation des formulaires
|
||||
(function () {
|
||||
'use strict'
|
||||
var forms = document.querySelectorAll('.needs-validation')
|
||||
|
||||
Array.prototype.slice.call(forms)
|
||||
.forEach(function (form) {
|
||||
form.addEventListener('submit', function (event) {
|
||||
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
|
||||
form.classList.add('was-validated')
|
||||
|
||||
}, false)
|
||||
})
|
||||
})()
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user