À propos de ce cours
Découvrez deux API du navigateur très utilisées : l'API Clipboard pour copier du texte ou une image dans le presse-papiers et le lire, et l'API Notifications pour afficher des messages système. La leçon présente les permissions, les conditions de sécurité, un exemple complet (bouton Copier, coller, rappel de pause), les options des notifications, leurs limites sur mobile et le rôle des Service Workers. Avec des activités corrigées.
-
Objectifs
- Copier du texte dans le presse-papiers et le lire avec l'API Clipboard.
- Demander la permission et afficher une notification système avec l'API Notifications.
- Respecter les règles de sécurité de ces API : contexte sécurisé, action de l'utilisateur, permissions.
-
L'API Clipboard (presse-papiers)
- Elle est accessible par
navigator.clipboard. Toutes ses méthodes renvoient une promesse: on les utilise avecawait. - Elle remplace l'ancienne commande
document.execCommand("copy"), aujourd'hui obsolète: ne l'utilisez plus dans un nouveau code.
Méthode Rôle Conditions writeText(texte)Copie du texte Contexte sécurisé, déclenchée par une action de l'utilisateur (clic, touche) readText()Lit le texte copié Le navigateur demande l'autorisation (ou affiche un bouton « Coller ») write([items])Copie un contenu riche : image PNG, HTML Comme writeTextread()Lit un contenu riche Comme readText- Cas d'usage : bouton « Copier » à côté d'un code, d'un lien de partage, d'un numéro de commande, d'un mot de passe généré, d'un code promo.

- Elle est accessible par
-
Exemple complet : copier, coller, rappeler
-
Copier du texte : les points clés
- On copie le
textContentde l'élément : le texte exact, sans balises. - Le retour visuel (« ✅ Copié ! » pendant 2 secondes) est indispensable : la copie est invisible pour l'utilisateur.
- On entoure l'appel de
try / catch: la copie peut échouer (page non sécurisée, onglet en arrière-plan, autorisation bloquée). - Pour copier une image, on passe un
ClipboardItemàwrite():
// Copier une image (PNG) : on passe par ClipboardItem async function copierImage(url) { const reponse = await fetch(url); const blob = await reponse.blob(); // type "image/png" await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]); } - On copie le
-
Lire le presse-papiers
- La lecture est plus sensible que l'écriture : le presse-papiers peut contenir un mot de passe ou un message privé. Le navigateur demande donc l'accord de l'utilisateur (Chrome affiche une demande d'autorisation, Firefox et Safari un petit bouton « Coller » à valider).
- Pour un simple champ de saisie, inutile d'utiliser l'API : le Ctrl + V de l'utilisateur fonctionne déjà. On peut aussi écouter l'événement
pasted'un élément et lireevent.clipboardData.getData("text").
La page suivante réunit les deux API de la leçon : un bouton qui copie une commande Git, un bouton qui colle le contenu du presse-papiers, et un rappel de pause sous forme de notification.
index.html:
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Presse-papiers et notifications</title>
<script src="presse.js" defer></script>
</head>
<body>
<h2>1. Copier un code</h2>
<pre id="code">git commit -m "Ajout du formulaire"</pre>
<button id="btn-copier" type="button">📋 Copier</button>
<h2>2. Coller</h2>
<button id="btn-coller" type="button">📥 Coller ici</button>
<p id="colle"></p>
<h2>3. Rappel de pause</h2>
<label>Dans <input id="minutes" type="number" min="1" max="120" value="25" /> minute(s)</label>
<button id="btn-rappel" type="button">🔔 Programmer</button>
<p id="etat-rappel"></p>
</body>
</html>
presse.js:
// ---------- 1. Copier du texte
const btnCopier = document.getElementById("btn-copier");
btnCopier.addEventListener("click", async () => {
const texte = document.getElementById("code").textContent;
try {
await navigator.clipboard.writeText(texte);
btnCopier.textContent = "✅ Copié !";
} catch (erreur) {
btnCopier.textContent = "❌ Échec";
console.error("Copie impossible :", erreur.message);
}
setTimeout(() => (btnCopier.textContent = "📋 Copier"), 2000);
});
// ---------- 2. Lire le presse-papiers (le navigateur demande l'autorisation)
document.getElementById("btn-coller").addEventListener("click", async () => {
const zone = document.getElementById("colle");
try {
const texte = await navigator.clipboard.readText();
zone.textContent = texte ? `Contenu : ${texte}` : "Le presse-papiers est vide.";
} catch {
zone.textContent = "Lecture refusée par le navigateur.";
}
});
// ---------- 3. Notification de rappel
const etatRappel = document.getElementById("etat-rappel");
async function autoriserNotifications() {
if (!("Notification" in window)) {
return false;
}
if (Notification.permission === "granted") {
return true;
}
if (Notification.permission === "denied") {
return false;
}
return (await Notification.requestPermission()) === "granted";
}
document.getElementById("btn-rappel").addEventListener("click", async () => {
if (!(await autoriserNotifications())) {
etatRappel.textContent = "Notifications refusées ou non disponibles.";
return;
}
const minutes = Number(document.getElementById("minutes").value);
etatRappel.textContent = `Rappel programmé dans ${minutes} minute(s). Laissez l'onglet ouvert.`;
setTimeout(() => {
const notif = new Notification("C'est l'heure de la pause ☕", {
body: `Vous travaillez depuis ${minutes} minute(s). Levez-vous et étirez-vous !`,
icon: "icone.png",
tag: "rappel-pause", // remplace un éventuel rappel précédent
});
notif.addEventListener("click", () => {
window.focus();
notif.close();
});
etatRappel.textContent = "";
}, minutes * 60 * 1000);
});
-
L'API Notifications
- Elle affiche un message en dehors de la page, dans le centre de notifications du système (Windows, macOS, Android…), même si l'utilisateur regarde un autre onglet.
- Trois étapes :
- Vérifier que l'API existe :
"Notification" in window. - Demander la permission, à la suite d'un clic :
await Notification.requestPermission()renvoie"granted","denied"ou"default"(l'utilisateur a fermé la demande sans répondre). - Créer la notification:
new Notification(titre, options).
Option Rôle bodyTexte sous le titre iconImage affichée à côté du message tagIdentifiant : une nouvelle notification de même tagremplace l'ancienne au lieu de s'empilerrequireInteractiontrue: reste affichée jusqu'à une action de l'utilisateur (selon le système)silenttrue: sans son ni vibration- L'objet créé émet des événements :
click(on ramène souvent l'utilisateur sur la page avecwindow.focus()),close,error. La méthodeclose()la ferme. - La propriété
Notification.permissiondonne l'état actuel sans rien demander.
-
Limites et bonnes pratiques des notifications
- Les notifications créées avec
new Notification()ne s'affichent que tant que la page est ouverte (dans un onglet, même en arrière-plan). Pour notifier un utilisateur qui a fermé le site (nouveau message, commande expédiée), il faut un Service Worker et les notifications push (Push API) envoyées par un serveur : c'est le fonctionnement des applications web installables (PWA). - Sur téléphone,
new Notification()n'est pas toujours disponible : sur Android, Chrome exige de passer par un Service Worker ; sur iPhone et iPad, seules les applications web ajoutées à l'écran d'accueil peuvent recevoir des notifications. - Ne demandez jamais la permission dès l'ouverture de la page : les navigateurs masquent ou bloquent automatiquement les sites qui le font. Expliquez d'abord à quoi serviront les notifications (« M'alerter s'il pleut »), puis demandez au clic.
- Un refus est définitif pour la page : respectez-le et n'insistez pas.
- Notifiez avec modération : trop de notifications poussent l'utilisateur à toutes les bloquer.
- Les notifications créées avec
-
Tester ces API
- Utilisez Live Server (
http://127.0.0.1:5500) : en ouvrant le fichier directement (file://), certaines fonctions sont bloquées. - Vérifiez que les notifications de votre navigateur sont autorisées dans les réglages du système (Windows : Paramètres → Système → Notifications) et que le mode « Ne pas déranger » est désactivé.
- Pour revenir à l'état « pas encore demandé » : icône à gauche de l'adresse → Réinitialiser les autorisations.
- Utilisez Live Server (
-
Activités
Activité 1 : boutons « Copier » automatiques
- Dans le dossier
clipboardde votre dépôtjs-api-navigateur, créez une page contenant au moins trois blocs<pre>avec des commandes Git. - Écrivez un script qui ajoute automatiquement un bouton « Copier » à chaque
<pre>de la page (querySelectorAll,createElement), avec le retour visuel « ✅ Copié ! ». - Utilisez un seul écouteur grâce à la délégation d'événements.
Activité 2 : générateur de mot de passe
- Créez un générateur de mot de passe de 16 caractères (lettres, chiffres, symboles) avec
crypto.getRandomValues(), et un bouton qui copie le résultat. - Pour plus de sécurité, videz le presse-papiers 30 secondes après la copie (
writeText("")). Que se passe-t-il si l'onglet n'est plus actif à ce moment-là ?
Activité 3 : minuteur Pomodoro
- Créez un minuteur de travail de 25 minutes suivi d'une pause de 5 minutes. Une notification annonce chaque changement de phase (utilisez
tagpour ne pas les empiler). - Le titre de l'onglet affiche le temps restant (
document.title). - Gérez les trois cas : permission accordée, refusée, API absente (dans ce cas, affichez un message dans la page).
Activité 4 : questions
- Pourquoi la lecture du presse-papiers est-elle plus contrôlée que l'écriture ?
- Quelle valeur renvoie
Notification.requestPermission()si l'utilisateur ferme la demande sans répondre ? - Un site d'actualités veut prévenir ses lecteurs d'une information urgente, même quand ils n'ont pas le site ouvert.
new Notification()suffit-il ?
Corrigés. Activité 2 : la copie programmée peut échouer, car le navigateur exige que la page ait le focus ; il faut donc un
try / catch. Activité 4 : le presse-papiers peut contenir des données privées copiées dans d'autres applications ; "default"; non, il faut un Service Worker et des notifications push envoyées par un serveur, car new Notification() ne fonctionne que si la page est ouverte.À retenir
await navigator.clipboard.writeText(texte)après un clic, avec un retour visuel et untry / catch.- La lecture (
readText()) est soumise à l'accord de l'utilisateur. - Notifications : vérifier l'API,
requestPermission()au clic, puisnew Notification(titre, { body, tag }). - Sans Service Worker, une notification n'est possible que si la page est ouverte.
Sources : MDN Web Docs, web.dev, W3C, WHATWG, open-meteo.com.