fix: guards DOM nuls sur tous les scripts + démarrage du roll outfit
All checks were successful
Deploy / Deploy to Production (push) Successful in 5s

Chaque script crash silencieusement si son élément racine est absent
de la page courante. Ajout de guards early-return dans jump.js,
roll.js et slideshow.js. Nettoyage du code mort dans script.js
(constantes inutilisées, onScroll vide, doublon nav.mainHeader).
Démarrage effectif de la boucle requestAnimationFrame dans rollOutfit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-06-22 11:13:25 +02:00
parent 2b832709f9
commit 4a84499761
5 changed files with 20 additions and 38 deletions

View file

@ -12,7 +12,6 @@
position: relative;
height: 100vh;
width: 100%;
perspective: 2000px;
transform-style: preserve-3d;
.outfit {
@ -27,7 +26,7 @@
opacity: 0;
transition: opacity 0.01s ease-in-out;
animation: flip 3s var(--curve) infinite;
animation: flip 3s var(--curve);
&.active {
opacity: 1;

View file

@ -88,6 +88,7 @@ export function initCharacterJump() {
let previousFrameTime = null;
const wrapper = document.querySelector(".characters");
if (!wrapper) return;
wrapper.addEventListener("mouseenter", () => { isHovered = true; });
wrapper.addEventListener("mouseleave", () => { isHovered = false; });

View file

@ -1,4 +1,4 @@
export function initFlipCarousel() {
export function initRollOutfit() {
const images = [
"assets/images/characters/characters-hypnotized.svg",
"assets/images/characters/characters-kawai.svg",
@ -7,8 +7,9 @@ export function initFlipCarousel() {
"assets/images/characters/characters-sunglasses.svg",
];
const outfits = document.querySelectorAll(".identity .outfit");
const container = document.querySelector(".identity");
if (!container) return;
const outfits = container.querySelectorAll(".outfit");
let currentIndex = 0;
let lastSwitch = 0;
@ -53,5 +54,7 @@ export function initFlipCarousel() {
}
};
requestAnimationFrame(rollOutfit);
return { images, getRotateX, switchImage };
}

View file

@ -2,47 +2,24 @@ import { initCharacterJump } from "./characters/jump.js";
import { initPupilTracking } from "./characters/pupilTracking.js";
import { initEventFilters } from "./filters.js";
import { CreditsSlideshow } from "./slideshow.js";
import { initFlipCarousel } from "./characters/roll.js";
import { initRollOutfit } from "./characters/roll.js";
document.addEventListener("DOMContentLoaded", () => {
const header = document.querySelector(".main-header");
const charactersWrapper = document.querySelector(".characters");
const logo = document.querySelector(".logo");
const svg = charactersWrapper.querySelector("svg");
const CHAR_SPEED = 0.6;
const LOGO_SPEED = 1.2;
const CHAR_WIDTH_MAX = 304;
const CHAR_WIDTH_MIN = 150;
// Valeurs initiales lues depuis l'attribut style HTML
const charMax = parseFloat(
charactersWrapper.style.getPropertyValue("--offset"),
);
const logoMax = logo.offsetHeight + 100;
const svg = charactersWrapper?.querySelector("svg");
let menuOpen = false;
let menuTransitioning = false;
function onScroll() {
if (menuOpen || menuTransitioning || header.classList.contains("small"))
return;
const scrollY = window.scrollY;
}
window.addEventListener("scroll", onScroll);
{
const nav = {
toggleBtn: document.querySelector(".toggle-nav"),
mainHeader: document.querySelector(".main-header"),
};
const toggleBtn = document.querySelector(".toggle-nav");
if (toggleBtn) {
function openMenu() {
menuOpen = true;
header.classList.add("menu-transitioning", "big");
nav.mainHeader.classList.add("open");
nav.toggleBtn.textContent = "fermer";
header.classList.add("open");
toggleBtn.textContent = "fermer";
document.body.style.overflow = "hidden";
}
@ -50,8 +27,8 @@ document.addEventListener("DOMContentLoaded", () => {
menuOpen = false;
menuTransitioning = true;
header.classList.remove("big");
nav.mainHeader.classList.remove("open");
nav.toggleBtn.textContent = "menu";
header.classList.remove("open");
toggleBtn.textContent = "menu";
document.body.style.overflow = "";
setTimeout(() => {
header.classList.remove("menu-transitioning");
@ -59,8 +36,8 @@ document.addEventListener("DOMContentLoaded", () => {
}, 500);
}
nav.toggleBtn.addEventListener("click", () => {
nav.mainHeader.classList.contains("open") ? closeMenu() : openMenu();
toggleBtn.addEventListener("click", () => {
header.classList.contains("open") ? closeMenu() : openMenu();
});
document.addEventListener("keydown", (event) => {
@ -75,8 +52,9 @@ document.addEventListener("DOMContentLoaded", () => {
}
initCharacterJump();
initPupilTracking(svg);
if (svg) initPupilTracking(svg);
initEventFilters();
initRollOutfit();
const gallery = new CreditsSlideshow(".gallery");
});

View file

@ -18,6 +18,7 @@ function prepareSlides(nodes) {
export class CreditsSlideshow {
constructor(slideshowSelector) {
this.node = document.querySelector(slideshowSelector);
if (!this.node) return;
this.slides = prepareSlides(this.node.querySelectorAll(".slide"));
this.init(this.slides);
this.next();