Debounce
Limiter la fréquence d’appel d’une fonction (recherche, resize).
function debounce(fn, wait) {
let t;
return function (...args) {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), wait);
};
}
Bibliothèque JavaScript
Même catalogue côté serveur (classe DesignLabCatalog en PHP) et filtrage équivalent en JS (DesignLabCatalogJS) pour une recherche instantanée.
API JSON : api/search.php?type=js&q=fetch
Recherche instantanée (JS) Live — saisissez dans le champ : la liste ci-dessous se met à jour sans recharger.
Limiter la fréquence d’appel d’une fonction (recherche, resize).
function debounce(fn, wait) {
let t;
return function (...args) {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), wait);
};
}
Requête GET avec parsing JSON et gestion d’erreur HTTP.
async function getJson(url) {
const res = await fetch(url, { credentials: 'same-origin' });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
Exécuter du code une fois le DOM chargé.
function onReady(fn) {
if (document.readyState !== 'loading') fn();
else document.addEventListener('DOMContentLoaded', fn);
}
Copie texte avec repli sur execCommand.
async function copyText(text) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
ta.remove();
}
Lire les query string en objet.
function getQueryParams() {
return Object.fromEntries(
new URLSearchParams(window.location.search)
);
}
Sauvegarder / lire une structure JSON.
function saveJson(key, value) {
localStorage.setItem(key, JSON.stringify(value));
}
function loadJson(key, fallback = null) {
const raw = localStorage.getItem(key);
if (raw == null) return fallback;
try {
return JSON.parse(raw);
} catch {
return fallback;
}
}
Un seul listener sur un parent pour des enfants dynamiques.
document.body.addEventListener('click', (e) => {
const btn = e.target.closest('[data-action]');
if (!btn) return;
const action = btn.getAttribute('data-action');
// …
});
Au plus une exécution par intervalle (scroll, resize).
function throttle(fn, ms) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last >= ms) {
last = now;
fn.apply(this, args);
}
};
}
Insérer du texte utilisateur sans XSS (template texte).
function escapeHtml(s) {
const div = document.createElement('div');
div.textContent = s;
return div.innerHTML;
}
Clé dédiée, stockage de l’e-mail côté client tant que l’onglet reste ouvert (js/acces.js).
const CLE_ACCES = 'carte_verte_email';
function definirAcces(email) {
sessionStorage.setItem(CLE_ACCES, email.trim());
}
function aUnAcces() {
const e = sessionStorage.getItem(CLE_ACCES);
return e !== null && e.trim().length > 0;
}
function retirerAcces() {
sessionStorage.removeItem(CLE_ACCES);
}
Redirection vers l’accueil si aucune session client (questionnaire.html).
function redirigerSiPasAcces() {
if (!aUnAcces()) {
window.location.href = 'index.html';
}
}
// Au chargement du questionnaire :
// redirigerSiPasAcces();
Blocs de questions avec points et numéro, base pour correction ou affichage (questionnaire.html).
// HTML : chaque bloc porte les métadonnées de scoring côté présentation.
// Exemple :
// <div data-points="2" data-question="1"> … radios … </div>
// <div data-type="plusieurs-reponses" data-points="2" data-question="4"> … cases à cocher … </div>
str_replace de marqueurs (__CSRF__, __QUESTIONS__) dans un fichier HTML (questionnaire.php).
// Côté PHP (logique équivalente) :
// $html = str_replace(
// ['__CSRF__', '__QUESTIONS__', '__MAX_POINTS__'],
// [$csrfHiddenInput, $questionsHtml, (string) $max],
// $html
// );