<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Événements et formulaires</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Événements DOM (clic, saisie, soumission), gestion des<br/>
événements en JavaScript, balises de formulaire HTML<br/>
(&lt;form&gt;, &lt;input&gt;, &lt;button&gt;, &lt;select&gt;), méthodes<br/>
HTTP GET et POST, validation côté client.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q01 : Événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>événement</strong> dans le contexte<br/>
d'une page web ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les éléments de la page <strong>déclenchent</strong> des<br/>
événements (clic, saisie, soumission) ; les<br/>
gestionnaires associés les <strong>écoutent</strong> et y<br/>
réagissent.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier média</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un fichier média (image,<br/>
son, vidéo) est une<br/>
ressource statique,<br/>
tandis qu'un évènement<br/>
est un signal dynamique<br/>
déclenché lors de<br/>
l'utilisation de la page.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de programmation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un bug n'est pas un événement DOM.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une modification CSS entièrement automatique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une modification CSS<br/>
relève de la mise en<br/>
forme. Un évènement,<br/>
en JavaScript, est un<br/>
signal émis par le<br/>
navigateur ou l'utilisateur,<br/>
auquel le code peut<br/>
réagir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une action de l'utilisateur ou du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les événements rendent la<br/>
page <strong>interactive</strong>. JavaScript permet<br/>
d'y réagir.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q02 : Événement de clic</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le nom de l'événement déclenché quand<br/>
l'utilisateur <strong>clique</strong> sur un élément ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Événements souris : click, dblclick,<br/>
mousedown, mouseup, mousemove,<br/>
mouseenter, mouseleave. Idem au clavier :<br/>
keydown, keyup, keypress.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>mouseDown</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un <strong>autre</strong> événement (pression<br/>
du bouton, sans relâcher).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>click</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : click est le nom<br/>
standard. Pour l'écouter :<br/>
el.addEventListener("click", ...).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>tap</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un événement tactile, distinct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>onclick</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'attribut/propriété d'écoute, pas<br/>
le nom de l'événement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q03 : Balise form</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise HTML délimite un <strong>formulaire</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le formulaire envoie ses données vers<br/>
action quand l'utilisateur soumet (par<br/>
clic sur &lt;button type="submit"&gt; ou en<br/>
validant via Entrée).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;send&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>&lt;form&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;form&gt; regroupe les<br/>
champs et permet de les soumettre<br/>
ensemble. Attributs clés : action<br/>
(URL), method (GET/POST).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;input&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : &lt;input&gt; est un <strong>champ</strong> de<br/>
formulaire, pas un conteneur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;formulaire&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q04 : Champ texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée un <strong>champ de saisie</strong> texte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Types courants d'&lt;input&gt; : text,<br/>
password, email, number, date,<br/>
checkbox, radio, submit, file.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;text size="20"&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>&lt;input type="text"&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;input&gt; est polyvalente,<br/>
type détermine son apparence et son<br/>
comportement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;textbox name="champ"&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;entry&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q05 : Bouton</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment créer un <strong>bouton</strong> « Envoyer » qui<br/>
soumet le formulaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois types de bouton : submit<br/>
(soumission, par défaut dans &lt;form&gt;),<br/>
reset (réinitialise les champs), button<br/>
(générique, à manipuler en JS).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;submit&gt;Envoyer&lt;/submit&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante ; submit<br/>
est une valeur de l'attribut type, pas<br/>
une balise.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;a&gt;Envoyer&lt;/a&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : &lt;a&gt; est un <strong>lien</strong>, pas un<br/>
bouton de soumission.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;button type="button"&gt;Envoyer&lt;/button&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : type="button" crée un bouton<br/>
inerte qui ne soumet <strong>pas</strong> le<br/>
formulaire ; il faut type="submit".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>&lt;button type="submit"&gt;Envoyer&lt;/button&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;button&gt; est plus<br/>
flexible (peut contenir du HTML, des<br/>
icônes). &lt;input type="submit"&gt; est<br/>
historique mais valide.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q06 : Liste déroulante</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée une <strong>liste déroulante</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Variantes : &lt;datalist&gt; (suggestions sur un<br/>
champ texte), multiple sur &lt;select&gt;<br/>
(sélection multiple).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;combo&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;dropdown&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;list&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>&lt;select&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;select&gt; est le<br/>
conteneur, chaque choix étant une<br/>
&lt;option value="..."&gt;texte&lt;/option&gt;<br/>
placée à l'intérieur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q07 : Étiquette</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert la balise &lt;label&gt; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique d'accessibilité : tout champ doit<br/>
avoir un &lt;label&gt; associé. Sans label, les<br/>
lecteurs d'écran ne peuvent pas annoncer<br/>
correctement le champ.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À mettre du texte en gras</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est &lt;strong&gt; ou &lt;b&gt;.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À étiqueter une variable interne du code JavaScript</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une variable JavaScript<br/>
n'a pas d'étiquette<br/>
accessible aux lecteurs<br/>
d'écran. La balise<br/>
&lt;label&gt; agit sur la<br/>
structure du formulaire<br/>
HTML, pas sur le code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Associer une étiquette à un champ de formulaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : améliore l'<strong>accessibilité</strong><br/>
et l'ergonomie. Lier via<br/>
&lt;label for="nomChamp"&gt;...&lt;/label&gt; et<br/>
&lt;input id="nomChamp"&gt;.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À créer un titre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait &lt;h1&gt;...&lt;h6&gt;.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q08 : Soumission</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel événement se déclenche quand un<br/>
<strong>formulaire est soumis</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour empêcher la soumission par défaut<br/>
(par exemple pour valider en JS) :<br/>
event.preventDefault() dans le<br/>
gestionnaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>click</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le clic sur le bouton déclenche click,<br/>
mais l'événement de soumission est<br/>
submit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>send</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : événement inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>submit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : événement submit<br/>
déclenché sur le &lt;form&gt;. À écouter pour<br/>
intercepter la soumission, par exemple pour<br/>
vérifier les champs avant l'envoi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>change</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un autre événement (changement de<br/>
valeur d'un champ).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q09 : GET ou POST ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle méthode HTTP utilise-t-on pour<br/>
<strong>envoyer un mot de passe</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle pratique : GET pour récupérer des<br/>
données (recherche, lecture), POST pour<br/>
modifier l'état du serveur (création, envoi<br/>
de formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>GET, à condition de masquer le champ avec type="password"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : type="password" masque seulement les<br/>
caractères à l'écran. Avec GET, le mot de passe<br/>
partirait quand même dans l'URL, visible dans<br/>
l'historique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>GET, parce que la requête est plus rapide à envoyer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : GET met les données dans l'URL,<br/>
ce qui est <strong>visible</strong> et logué dans<br/>
l'historique. À éviter pour les données<br/>
sensibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>POST, les données voyageant dans le corps de la requête</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : avec POST, rien ne<br/>
transite par l'URL. Pour les données<br/>
sensibles, utiliser POST + HTTPS.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux, HTTP ne convenant pas aux données sensibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour transmettre un mot<br/>
de passe, on choisit<br/>
systématiquement la<br/>
méthode POST (avec HTTPS),<br/>
qui place les données dans<br/>
le corps de la requête<br/>
plutôt que dans l'URL.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q10 : Formulaire complet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel de ces fragments est un <strong>formulaire valide</strong> demandant un nom et l'envoyant en<br/>
POST ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Attribut <strong>name</strong> essentiel : c'est sous<br/>
ce nom que la donnée arrive côté serveur.<br/>
Sans name, le champ n'est <strong>pas envoyé</strong>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>html<br/>
&lt;form action="/save" method="POST"&gt;<br/>
  Nom : &lt;input name="nom" type="text"&gt;<br/>
  &lt;input type="button" value="Envoyer"&gt;<br/>
&lt;/form&gt;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : type="button" crée un bouton<br/>
inerte qui ne déclenche <strong>pas</strong> la<br/>
soumission. Il faut type="submit" (ou<br/>
un &lt;button&gt; dont le type par défaut est<br/>
submit).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>`<code>html<br/>
&lt;form action="/save" method="POST"&gt;<br/>
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;<br/>
  &lt;input id="nom" name="nom" type="text"&gt;<br/>
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;<br/>
&lt;/form&gt;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;form&gt; avec action et<br/>
method, &lt;label&gt; lié à &lt;input&gt; par<br/>
for/id, name (essentiel pour<br/>
identifier la donnée envoyée), bouton<br/>
submit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>html<br/>
&lt;form action="/save" method="POST"&gt;<br/>
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;<br/>
  &lt;input id="nom" type="text"&gt;<br/>
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;<br/>
&lt;/form&gt;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque l'attribut name sur<br/>
le champ. Sans name, la donnée saisie<br/>
n'est <strong>pas envoyée</strong> au serveur, même si<br/>
le formulaire se soumet sans erreur<br/>
apparente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>`<code>html<br/>
&lt;form action="/save"&gt;<br/>
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;<br/>
  &lt;input id="nom" name="nom" type="text"&gt;<br/>
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;<br/>
&lt;/form&gt;<br/>
</code>`</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans attribut method, le<br/>
formulaire est envoyé avec la méthode par<br/>
défaut, <strong>GET</strong> (données visibles dans<br/>
l'URL), et non en POST comme demandé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q11 : Gestionnaire d'événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel code attache la fonction handleClick au<br/>
clic sur le bouton btn ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Avantage d'addEventListener sur<br/>
btn.onclick = handleClick : on peut attacher<br/>
<strong>plusieurs</strong> gestionnaires au même événement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>btn.attachEvent("onclick", handleClick)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : attachEvent est l'ancienne API<br/>
propriétaire d'Internet Explorer,<br/>
abandonnée ; le standard est<br/>
addEventListener.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>btn.onclick(handleClick)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : onclick est une <strong>propriété</strong>,<br/>
pas une méthode. Il faut écrire<br/>
btn.onclick = handleClick.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>btn.click(handleClick)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : btn.click() <strong>déclenche</strong> le<br/>
clic, ne l'écoute pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>btn.addEventListener("click", handleClick)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : forme moderne et<br/>
recommandée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q12 : Lire la valeur d'un champ</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment récupérer la valeur tapée dans<br/>
&lt;input id="nom"&gt; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour modifier aussi : el.value =<br/>
"nouveau". Pour les cases à cocher et les<br/>
boutons radio : el.checked (booléen).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>document.getElementById("nom").content</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>document.getElementById("nom").text</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est value, pas text.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>document.getElementById("nom").value</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : value est la propriété<br/>
standard pour les champs de formulaire<br/>
(&lt;input&gt;, &lt;select&gt;, &lt;textarea&gt;).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>document.getElementById("nom").innerHTML</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : innerHTML est pour le contenu<br/>
HTML d'éléments génériques, pas pour les<br/>
champs de formulaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q13 : preventDefault</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert event.preventDefault() dans un<br/>
gestionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas typique : valider un formulaire en JS<br/>
avant de le soumettre.<br/>
`<code>js<br/>
form.addEventListener("submit", e =&gt; {<br/>
  if (!valider()) e.preventDefault();<br/>
});<br/>
</code>`</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À empêcher tous les événements futurs sur la page</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul le comportement par défaut<br/>
de l'événement <strong>courant</strong> est annulé,<br/>
les événements suivants restent actifs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À fermer la page courante après l'événement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fermeture d'une page<br/>
se demande via window.close().<br/>
La méthode preventDefault<br/>
ne ferme rien : elle annule<br/>
uniquement l'action par<br/>
défaut associée à un<br/>
évènement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À effacer les messages affichés dans la console</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'effacement de la<br/>
console se fait avec<br/>
console.clear(). La<br/>
méthode preventDefault<br/>
n'agit que sur l'évènement<br/>
en cours, pas sur les<br/>
outils du navigateur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Empêcher le comportement par défaut du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : très utile pour<br/>
intercepter une soumission ou un clic<br/>
sur un lien (&lt;a&gt;) afin de gérer<br/>
l'action en JavaScript.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q14 : Validation HTML5</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment indiquer qu'un champ est<br/>
<strong>obligatoire</strong> dans le HTML ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres attributs de validation HTML5 :<br/>
min, max, minlength, maxlength,<br/>
type="email", etc.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec l'attribut must-fill</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : attribut inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec l'attribut required</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : &lt;input required&gt; active<br/>
la validation native du navigateur, qui<br/>
empêche la soumission si le champ est<br/>
vide, avec un message standard<br/>
automatique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec mandatory="true"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : attribut inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il faut une fonction JavaScript</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais HTML5 offre des<br/>
validations natives plus simples.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q15 : Type d'input adapté</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel <strong>type</strong> d'&lt;input&gt; est le plus adapté<br/>
pour un champ « Âge » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choisir le bon type améliore l'ergonomie<br/>
(clavier mobile adapté), accessibilité et<br/>
validation. Ne pas négliger ces<br/>
« petits détails ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="age"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : type inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="email"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour un courriel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>type="number"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : restreint à des nombres,<br/>
affiche des flèches haut/bas, ouvre un<br/>
clavier numérique sur mobile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="text"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu pratique. L'utilisateur<br/>
pourrait taper du texte.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q16 : Cible de l'événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un gestionnaire d'événement, comment<br/>
accéder à l'<strong>élément</strong> sur lequel l'événement<br/>
a eu lieu ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>event.target désigne l'élément sur lequel<br/>
l'événement s'est produit : un même<br/>
gestionnaire peut ainsi servir à plusieurs<br/>
boutons et savoir lequel a été cliqué.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>event.target</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : référence l'élément<br/>
ayant déclenché l'événement. Permet de<br/>
partager un même gestionnaire entre<br/>
plusieurs éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>event.dom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>this.element</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : this.element n'existe pas.<br/>
L'élément sur lequel l'événement a eu<br/>
lieu s'obtient avec event.target.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>event.element</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q17 : Attribut name</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi l'attribut name est-il important<br/>
pour un &lt;input&gt; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinction triple : id (unique, pour CSS<br/>
et JS), class (pour CSS et JS, partagé),<br/>
name (pour la soumission du formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour le nom affiché</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le rôle de &lt;label&gt;.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour le validateur HTML automatique du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Indirectement, mais le rôle principal est<br/>
autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il identifie la donnée envoyée au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans name, le champ<br/>
n'est <strong>pas envoyé</strong> au serveur. Le<br/>
serveur reçoit nom=Alice&amp;age=17 à<br/>
partir des name.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour la couleur du champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est CSS.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q18 : Zone de texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée une <strong>zone de texte multiligne</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Particularité : &lt;textarea&gt; n'est pas<br/>
auto-fermante, et son contenu initial<br/>
est entre les balises (pas un attribut<br/>
value).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;paragraph contenteditable&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais usage avancé, pas un<br/>
formulaire classique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;input type="text" multiline&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : multiline n'existe pas comme<br/>
attribut de &lt;input&gt;.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>&lt;text&gt;multiligne&lt;/text&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>&lt;textarea&gt;contenu initial&lt;/textarea&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : balise dédiée. Attributs<br/>
utiles : rows, cols, placeholder,<br/>
maxlength.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q19 : Événement input vs change</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre les événements<br/>
input et change sur un &lt;input type="text"&gt; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choix selon le besoin : aperçu en direct →<br/>
input ; validation à la fin → change ;<br/>
soumission complète → submit (sur le<br/>
formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>change plante systématiquement toujours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'évènement change<br/>
fonctionne parfaitement<br/>
et n'a aucune raison<br/>
structurelle d'échouer.<br/>
Il sert simplement à<br/>
réagir lorsque la<br/>
nouvelle valeur est<br/>
confirmée par l'utilisateur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>input à chaque touche, change à la fin</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : input est plus<br/>
réactif (auto-complétion en temps réel),<br/>
change plus économe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>input n'existe pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : événement standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : différence de fréquence.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q20 : Requête HTTP</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quand on soumet un formulaire en POST vers<br/>
/save, que se passe-t-il <strong>côté navigateur</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le serveur traite les données reçues<br/>
(calcul, enregistrement) et renvoie une<br/>
nouvelle page, que le navigateur affiche à<br/>
la place du formulaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une requête POST part vers /save, puis la réponse s'affiche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le mécanisme<br/>
fondamental du formulaire. Le navigateur<br/>
envoie la requête, puis affiche la page<br/>
renvoyée par le serveur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le formulaire reste affiché tel quel, sans requête réseau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas par défaut : une requête part et la<br/>
page <strong>change</strong> pour afficher la réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le navigateur ouvre carrément un autre site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le navigateur ne quitte<br/>
pas le domaine courant<br/>
de sa propre initiative.<br/>
Il envoie simplement<br/>
une requête vers l'URL<br/>
indiquée par l'attribut<br/>
action du formulaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, tant qu'un script JavaScript n'envoie pas les données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la soumission est native, aucun<br/>
JavaScript n'est nécessaire pour qu'un<br/>
formulaire envoie ses données.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q21 : Validation client vs serveur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Faut-il valider les données d'un formulaire<br/>
<strong>côté client</strong> (JavaScript), <strong>côté serveur</strong><br/>
ou les deux ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mantra de sécurité : « Never trust user<br/>
input. » La validation côté client améliore<br/>
l'expérience, mais la validation côté<br/>
serveur est <strong>non négociable</strong>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Côté serveur uniquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu ergonomique :<br/>
l'utilisateur doit attendre la réponse<br/>
du serveur pour voir une erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux : faire confiance</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : recette pour les bugs et failles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Côté client uniquement, car plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la validation client peut être<br/>
contournée (l'utilisateur peut<br/>
désactiver JS, modifier le HTML,<br/>
envoyer une requête falsifiée). Pas de<br/>
sécurité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les deux, pour l'ergonomie et la sécurité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : règle d'or. Toute<br/>
donnée venant du client est suspecte<br/>
jusqu'à validation par le serveur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q22 : Un paragraphe qui réagit au survol</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une page contient &lt;p id="zone"&gt;Survolez-moi&lt;/p&gt; et le script :</p>
<p>`<code>javascript<br/>
const zone = document.getElementById("zone");<br/>
zone.addEventListener("mouseover", () =&gt; {<br/>
  zone.textContent = "Dedans";<br/>
});<br/>
zone.addEventListener("mouseout", () =&gt; {<br/>
  zone.textContent = "Dehors";<br/>
});<br/>
</code>`</p>
<p>L'utilisateur amène le pointeur sur le paragraphe, clique deux<br/>
fois dessus, puis éloigne le pointeur. Qu'affiche alors le<br/>
paragraphe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Chaque événement a son gestionnaire : mouseover à l'arrivée<br/>
du pointeur sur l'élément, mouseout à son départ, click au<br/>
clic. Un clic ne déclenche donc ni mouseover ni mouseout.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>DedansDehors</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : affecter textContent remplace tout le texte<br/>
du paragraphe, sans rien ajouter à la suite. Le dernier<br/>
gestionnaire exécuté ne laisse que Dehors.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dehors</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'arrivée du pointeur déclenche<br/>
mouseover (texte Dedans), les clics ne déclenchent<br/>
aucun de ces deux gestionnaires, et le départ du<br/>
pointeur déclenche mouseout, qui écrit Dehors.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Survolez-moi</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le texte initial ne revient pas tout seul.<br/>
Chaque gestionnaire remplace le contenu du paragraphe,<br/>
et le dernier exécuté, celui de mouseout, écrit<br/>
Dehors.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dedans</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les clics ne figent pas le texte. Quand le<br/>
pointeur quitte le paragraphe, l'événement mouseout<br/>
se produit et son gestionnaire écrit Dehors.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q23 : Bug formulaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Mon formulaire en POST envoie au serveur, mais<br/>
le champ « nom » est <strong>vide</strong> côté serveur.<br/>
Quelle est la cause la plus probable ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Réflexe de débogage : ouvrir l'onglet<br/>
Network des outils développeur, regarder la<br/>
requête envoyée et son contenu (« Form<br/>
Data »).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur est en panne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais cela donnerait une autre<br/>
erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le bouton submit est cassé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu probable si la requête<br/>
arrive au serveur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'attribut name manque sur l'&lt;input&gt;</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le piège classique.<br/>
&lt;input id="nom"&gt; ne suffit pas ; il<br/>
faut &lt;input name="nom"&gt; (l'id n'est<br/>
pas envoyé).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le navigateur n'autorise pas la méthode POST</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : POST est standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q24 : Un mot de passe envoyé sans chiffrement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le formulaire de connexion d'un site commence par :</p>
<p>`<code>html<br/>
&lt;form action="http://exemple.fr/connexion" method="post"&gt;<br/>
</code></p>
<p>L'adresse commence par http:// et non par https://`. Que<br/>
risque l'utilisateur qui envoie son mot de passe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux choix distincts : GET ou POST décide où voyagent les<br/>
paramètres (URL ou corps de la requête) ; HTTP ou HTTPS<br/>
décide si la transmission est chiffrée. Un mot de passe<br/>
exige POST <strong>et</strong> HTTPS.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le mot de passe apparaît dans l'URL et dans l'historique du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le cas avec GET. Ici, method="post"<br/>
place les données dans le corps de la requête, qui<br/>
circule toutefois en clair.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun risque : la méthode POST chiffre les données envoyées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : POST évite seulement que les données<br/>
apparaissent dans l'URL. Le chiffrement est assuré<br/>
par HTTPS, pas par le choix de la méthode.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur refuse la requête, car POST exige une adresse https://</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'impose HTTPS pour une requête POST.<br/>
Le serveur reçoit bien le mot de passe, mais la<br/>
transmission n'est pas protégée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le mot de passe circule en clair et peut être lu s'il est intercepté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : POST place les données dans le corps<br/>
de la requête, mais sans HTTPS ce corps n'est pas<br/>
chiffré. Quiconque intercepte la communication, par<br/>
exemple sur un Wi-Fi public, lit le mot de passe.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes, laquelle<br/>
est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mnémonique sécurité : « Never trust user<br/>
input + always use HTTPS pour les données<br/>
sensibles ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La méthode HTTP GET est préférable pour transmettre un mot de passe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : GET met les<br/>
données dans l'URL (visibles, loguées).<br/>
Pour un mot de passe, utiliser POST sur<br/>
HTTPS.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'attribut name d'un champ est essentiel pour la soumission au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : sans name, pas envoyé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toute donnée client doit être revalidée côté serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : règle d'or de sécurité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un événement DOM peut être écouté avec addEventListener</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
exacte : addEventListener<br/>
est la méthode standard<br/>
pour attacher un<br/>
gestionnaire à un<br/>
évènement. Ce n'est<br/>
donc pas la mauvaise<br/>
affirmation recherchée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q26 : Type d'input pour une adresse e-mail</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel attribut type choisir pour un champ destiné à<br/>
la saisie d'une adresse électronique ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choisir le bon type apporte un triple bénéfice :<br/>
validation native du navigateur, clavier adapté<br/>
sur mobile, et meilleure information aux<br/>
technologies d'assistance. Quelques types utiles :<br/>
email, tel, url, number, date, color,<br/>
password.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="text"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un champ texte fonctionne, mais<br/>
n'apporte aucune validation automatique. On<br/>
perd les vérifications de format et le clavier<br/>
spécialisé sur mobile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>type="email"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ce type indique au navigateur<br/>
qu'il s'agit d'une adresse électronique. Cela<br/>
déclenche une validation de base (présence<br/>
d'un @), affiche un clavier adapté sur<br/>
mobile et améliore l'accessibilité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="contact"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : contact n'est pas un type d'input<br/>
valide. La liste exhaustive des types est<br/>
fixée par le standard HTML.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>type="address"</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun type address n'est défini par<br/>
le standard HTML. Le type spécifique aux<br/>
adresses électroniques est email.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q27 : Validation côté navigateur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel attribut HTML5 rend un champ de formulaire<br/>
<strong>obligatoire</strong>, en empêchant la soumission tant<br/>
qu'il est vide ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres attributs de validation native :<br/>
minlength/maxlength (longueur de la chaîne),<br/>
min/max (valeur numérique ou date). La<br/>
validation côté navigateur n'exempte pas d'une<br/>
revalidation côté serveur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>mandatory</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun attribut mandatory n'est<br/>
défini dans le standard HTML. C'est required<br/>
qui joue ce rôle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>obligatoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les attributs HTML sont en anglais.<br/>
Le bon attribut est required.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>empty=false</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune syntaxe de ce type n'existe en<br/>
HTML. L'attribut required se passe de<br/>
valeur : sa simple présence suffit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>required</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ajouter required à un champ<br/>
empêche le navigateur de soumettre le<br/>
formulaire tant qu'il est vide. Un message<br/>
d'erreur s'affiche automatiquement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q28 : Ce qu'est un cookie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>cookie</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le protocole HTTP ne garde aucun souvenir d'une<br/>
requête à l'autre. Pour reconnaître un visiteur, le<br/>
serveur lui confie un cookie : le navigateur le<br/>
mémorise et le joint à toutes ses requêtes vers ce<br/>
site. Connexion maintenue, panier, langue choisie :<br/>
tout cela passe par des cookies.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un petit texte déposé par le serveur, gardé par le navigateur et renvoyé à chaque requête vers le site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est le mécanisme qui permet au serveur de<br/>
reconnaître un navigateur d'une requête à<br/>
l'autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier conservé sur le serveur qui contient l'historique complet de chaque visiteur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cookie est rangé chez le client, dans le<br/>
navigateur ; le serveur ne garde que ce que le<br/>
navigateur lui renvoie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un programme que le serveur fait exécuter au navigateur à chaque visite pour reconnaître l'ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un cookie ne contient pas de code et ne s'exécute<br/>
pas ; c'est une donnée, stockée côté client.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une image gardée dans le cache du navigateur pour accélérer l'affichage des pages déjà vues</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cache stocke des ressources de pages ; un<br/>
cookie porte une information d'identification ou<br/>
de préférence, pas une image.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q29 : Connecté le lendemain sans ressaisir le mot de passe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sur un site, vous cochez « rester connecté »,<br/>
fermez le navigateur et revenez le lendemain : vous<br/>
êtes toujours identifié. Où l'information a-t-elle<br/>
été conservée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le navigateur stocke le cookie sur le disque, avec<br/>
une date d'expiration. Tant qu'elle n'est pas<br/>
passée, chaque requête vers le site l'emporte, et le<br/>
serveur retrouve la session associée. Se déconnecter<br/>
revient à faire effacer ce cookie.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dans un cookie gardé par le navigateur et renvoyé au serveur à la nouvelle visite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le serveur y a inscrit un jeton de session ; en<br/>
le recevant, il reconnaît votre compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans une variable JavaScript de la page, qui survit à la fermeture du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les variables d'un script disparaissent dès que<br/>
la page est fermée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Nulle part : le serveur reconnaît votre ordinateur grâce à son adresse IP</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'adresse IP change souvent et est partagée par<br/>
plusieurs appareils d'un même réseau : elle ne<br/>
peut pas identifier un compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans le code HTML de la page, modifié par le serveur pour y inscrire votre nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le HTML reçu est reconstruit à chaque requête ; il<br/>
ne persiste pas sur votre machine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q30 : Mémoriser une préférence : chez le client ou sur le serveur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un site propose un choix de langue. Deux solutions :<br/>
(A) enregistrer la langue dans un cookie ; (B)<br/>
l'enregistrer dans la base de données du serveur,<br/>
associée au compte de l'utilisateur. Laquelle<br/>
retrouve la langue choisie quand l'utilisateur se<br/>
connecte depuis un autre ordinateur ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce qui est mémorisé dans le client (cookie, stockage<br/>
du navigateur) reste sur cette machine. Ce qui est<br/>
mémorisé par le serveur suit le compte. Le choix<br/>
dépend de l'usage : un cookie suffit pour un<br/>
visiteur anonyme, la base du serveur s'impose pour<br/>
un utilisateur identifié.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux, car le navigateur transmet ses cookies au nouvel ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Rien ne transfère les cookies d'une machine à<br/>
l'autre ; chaque navigateur a les siens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux : une préférence ne se mémorise que pendant la visite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les deux solutions survivent à la fin de la<br/>
visite ; seule la seconde survit au changement de<br/>
machine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La solution B seule, car la préférence est stockée côté serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Quelle que soit la machine, une fois connecté,<br/>
l'utilisateur retrouve ce que le serveur a<br/>
mémorisé pour son compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La solution A seule, car le cookie accompagne l'utilisateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cookie reste dans le navigateur où il a été<br/>
déposé ; un autre ordinateur n'en a aucune copie.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q31 : Le trajet d'un cookie entre deux requêtes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Première requête vers boutique.fr : le serveur<br/>
répond avec l'en-tête Set-Cookie: panier=42.<br/>
Quelques secondes plus tard, le navigateur demande<br/>
une autre page du même site. Que contient cette<br/>
deuxième requête ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux en-têtes se répondent : Set-Cookie dans la<br/>
réponse du serveur dépose la valeur, Cookie dans<br/>
les requêtes suivantes du navigateur la renvoie. Le<br/>
serveur retrouve ainsi le panier numéro 42 sans<br/>
que l'utilisateur ait rien ressaisi.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un en-tête Cookie: panier=42, ajouté automatiquement par le navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le navigateur joint à chaque requête vers<br/>
boutique.fr les cookies que ce site lui a<br/>
confiés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un en-tête Set-Cookie: panier=42, renvoyé tel quel au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Set-Cookie est un en-tête de réponse, du serveur<br/>
vers le navigateur ; dans l'autre sens, l'en-tête<br/>
s'appelle Cookie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien de particulier : c'est au serveur de redemander la valeur du panier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le serveur n'a aucun moyen de « redemander » :<br/>
HTTP est sans mémoire, c'est le client qui<br/>
renvoie l'information.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le cookie panier=42, envoyé aussi à tous les autres sites visités ensuite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un cookie n'est renvoyé qu'au site qui l'a<br/>
déposé ; les autres sites ne le voient pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q32 : L'événement déclenché par l'envoi</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel événement se produit sur un élément form lorsque<br/>
l'utilisateur clique sur son bouton d'envoi ou appuie sur Entrée<br/>
dans un champ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Écouter submit sur le formulaire couvre tous les moyens d'envoi,<br/>
bouton comme touche Entrée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>input</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : input est émis à chaque modification d'un champ.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>send</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cet événement n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>submit</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : submit est émis par le formulaire lui-même,<br/>
quel que soit le moyen de l'envoyer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>click</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : click est émis par le bouton, pas par le formulaire,<br/>
et la touche Entrée ne le déclenche pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q33 : Une valeur lue trop tôt</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Ce script affiche toujours une chaîne vide au clic. Pourquoi ?<br/>
`<code>javascript<br/>
const nom = document.getElementById("nom").value;<br/>
document.getElementById("btn").addEventListener("click", function () {<br/>
    alert("Bonjour " + nom);<br/>
});<br/>
</code>`</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une valeur de formulaire change avec l'utilisateur : elle se lit au<br/>
moment de l'événement, pas une fois pour toutes au chargement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le gestionnaire doit être attaché au champ et non au bouton</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le bouton est une cible correcte ; le problème est le<br/>
moment de la lecture.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>alert ne peut pas afficher une variable, seulement un texte fixe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : alert affiche n'importe quelle chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le champ nom n'a pas d'attribut name, donc pas de valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : name sert à l'envoi, pas à la lecture de .value.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La valeur est lue au chargement, avant la saisie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : nom reçoit la valeur du champ au moment où le<br/>
script s'exécute, c'est-à-dire vide. Lire .value à l'intérieur<br/>
de la fonction donne la saisie du moment.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q34 : Savoir quelle touche a été pressée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un gestionnaire de l'événement keydown, comment savoir<br/>
quelle touche l'utilisateur a enfoncée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le paramètre event d'un gestionnaire décrit ce qui s'est passé :<br/>
touche pressée, position de la souris, élément visé.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En comparant le texte du champ avant et après la frappe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est possible mais peu fiable, et inutile puisque<br/>
l'événement donne la touche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En appelant keyboard.last()</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette fonction n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>En lisant event.key</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'objet événement reçu en paramètre porte la<br/>
touche dans key, par exemple "Enter" ou "a".</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En lisant event.value</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : value est une propriété des champs de saisie, pas de<br/>
l'événement clavier.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q35 : Texte indicatif ou valeur préremplie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle différence entre &lt;input placeholder="Votre nom"&gt; et<br/>
&lt;input value="Votre nom"&gt; ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un placeholder aide l'utilisateur sans rien envoyer ; une value<br/>
est une donnée, parfois envoyée par erreur si on l'oublie.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, les deux attributs étant synonymes et envoyés tous deux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'un guide, l'autre remplit ; seul value est transmis.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le premier concerne les champs texte, le second les boutons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux s'appliquent aux champs de saisie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le premier affiche une indication grisée, le second préremplit le champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : placeholder n'est pas une valeur, elle n'est<br/>
pas envoyée ; value est le contenu réel du champ, envoyé tel<br/>
quel si l'utilisateur ne le change pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le premier est obligatoire, le second facultatif pour le navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux sont facultatifs ; l'obligation de saisie vient<br/>
de required.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q36 : Un champ numérique borné</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que garantit &lt;input type="number" min="0" max="20" name="note"&gt;<br/>
lors de l'envoi du formulaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La validation côté client améliore l'expérience ; la validation côté<br/>
serveur garantit la sécurité. Les deux sont nécessaires.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un blocage par le navigateur hors de [0, 20], le serveur devant revérifier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la vérification du navigateur protège contre les<br/>
erreurs de saisie, pas contre une requête fabriquée à la main.<br/>
Le serveur reste responsable de la validation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, ces attributs ne servant qu'à l'affichage du champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le navigateur les utilise bien pour bloquer l'envoi<br/>
d'une valeur hors bornes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur est automatiquement arrondie à l'entier le plus proche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : min et max bornent, ils n'arrondissent pas ; step<br/>
règle les valeurs permises.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur ne peut recevoir que des valeurs entre 0 et 20, garanties</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une requête envoyée sans passer par le formulaire peut<br/>
contenir n'importe quoi.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
