jQuery / Méthode / .prop() - Lire et définir les propriétés DOM

Dans jQuery, .prop("nom") lit une propriété DOM du premier élément sélectionné ; .prop("nom", valeur) la définit sur tous les éléments sélectionnés. Utilisez .prop("checked") pour l’état coché actuel et .prop("disabled") pour l’état désactivé. Distinguez les propriétés actuelles du navigateur des chaînes d’attributs écrites en HTML.

État actuel et attributs HTML

Le modèle objet du document (DOM) représente le HTML sous forme de nœuds et d’objets. checked, disabled et selectedIndex sont des propriétés de ces objets dans l’API .prop(). .attr() lit et définit les attributs HTML. Un même nom ne désigne pas toujours le même état actuel.

Question Méthode Signification
Actuellement coché ? .prop("checked") Booléen true/false actuel
État coché par défaut ? .prop("defaultChecked") Valeur par défaut correspondant à l’attribut checked
Attribut HTML lui-même ? .attr("checked") ou getAttribute("checked") Attribut qui ne suit pas les clics
Valeur du contrôle ? .val() value ou valeur sélectionnée, distincte de l’état coché

<input type="checkbox" checked=""> commence coché. Le décocher met checked à false, sans changer defaultChecked ni l’attribut. L’attribut checked de la case est booléen : sa présence compte. checked="false" ne signifie donc pas décoché.

Ne déduisez pas l’état actuel de la chaîne .attr("checked"). Avec checked="" ici, 3.7.1 renvoyait "checked" et 4.0.0 la chaîne vide "". Une chaîne vide est fausse dans une condition JavaScript alors que la case peut être cochée. Lisez le booléen .prop("checked") plutôt que de comparer des chaînes dépendant de la version.

Exemple complet des états et événements change

Enregistrez tout le code en UTF-8 dans prop-demo.html et ouvrez-le dans le navigateur. Internet est nécessaire pour le fichier jQuery officiel 4.0.0 du réseau de diffusion de contenu (CDN), sans installation. Ces interactions et extraits de console ont été exécutés avec 3.7.1 et 4.0.0. Le getAttribute() natif affiche l’attribut de manière identique dans les deux versions.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Read and change DOM properties</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
    button { font: inherit; margin: 4px; max-width: 100%; }
    label { display: block; padding: 12px; border: 1px solid #aab; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Current properties and markup attributes</h1>
  <form id="demo-form">
    <label><input type="checkbox" id="subscribe" name="subscription" value="weekly" checked=""> Weekly subscription</label>
  </form>
  <button type="button" id="toggle">Toggle checked</button>
  <button type="button" id="set">Set unchecked and disabled</button>
  <button type="button" id="enable">Enable</button>
  <button type="button" id="notify">Check and trigger change</button>
  <button type="button" id="reset">Reset</button>
  <pre id="result" aria-live="polite"></pre>
  <script>
    $(function () {
      const $box = $("#subscribe");
      let changes = 0;
      function report() {
        $("#result").text(`checked=${$box.prop("checked")}\ndefaultChecked=${$box.prop("defaultChecked")}\nchecked attribute=${JSON.stringify($box.get(0).getAttribute("checked"))}\ndisabled=${$box.prop("disabled")}\nvalue=${$box.val()}\nchange events=${changes}`);
      }
      $box.on("change", function () { changes++; report(); });
      $("#toggle").on("click", function () { $box.prop("checked", function (index, old) { return !old; }); report(); });
      $("#set").on("click", function () { $box.prop({ checked: false, disabled: true }); report(); });
      $("#enable").on("click", function () { $box.prop("disabled", false); report(); });
      $("#notify").on("click", function () { $box.prop("checked", true).trigger("change"); });
      $("#reset").on("click", function () { $("#demo-form").get(0).reset(); $box.prop("disabled", false); changes = 0; report(); });
      report();
    });
  </script>
</body>
</html>

Voici le résultat initial. Les deux guillemets après checked attribute signifient que l’attribut existe avec une valeur vide. Sans attribut, getAttribute() renverrait null.

checked=true
defaultChecked=true
checked attribute=""
disabled=false
value=weekly
change events=0
  1. Toggle checked met checked à false sans changer la valeur par défaut, l’attribut ni value. change events reste à zéro.
  2. Cochez directement la case : change events augmente de un. Comparez séparément modification d’état et notification d’événement.
  3. Set unchecked and disabled applique .prop({ checked: false, disabled: true }). La case est décochée et ne peut plus être manipulée directement.
  4. Enable remet disabled à false sans cocher la case.
  5. Check and trigger change met checked à true puis déclenche explicitement change. Le compteur augmente ; définir la propriété seule n’exécute pas le gestionnaire.
  6. Reset restaure l’état coché par défaut, enlève séparément disabled et remet le compteur à zéro. Répéter donne le même résultat initial.

Ne supposez pas que reset() restaure aussi disabled : l’exemple le retire explicitement. Déclencher change avertit les gestionnaires enregistrés, sans reproduire une interaction physique complète du pointeur. Si seule une actualisation de l’affichage est nécessaire après une modification programmée, appelez directement une fonction telle que report().

Objet, fonction et selectedIndex

Un objet définit plusieurs propriétés ; une fonction calcule une valeur par élément. Elle reçoit l’index commençant à zéro et l’ancienne valeur, puis renvoie la nouvelle. Après Reset, exécutez cet extrait complet dans la console des outils de développement. Il crée deux cases temporaires, inverse leurs états, les désactive et les supprime à la fin.

const $holder = $('<div><input type="checkbox" checked><input type="checkbox"></div>').appendTo("body");
const $boxes = $holder.find("input");
console.log(`before=${$boxes.map(function () { return this.checked; }).get().join(",")}`);
$boxes.prop("checked", function (index, old) { return !old; });
$boxes.prop({ disabled: true });
console.log(`after=${$boxes.map(function () { return this.checked; }).get().join(",")}`);
console.log(`first getter=${$boxes.prop("checked")}; type=${typeof $boxes.prop("checked")}`);
console.log(`disabled count=${$boxes.filter(":disabled").length}`);
console.log(`empty getter=${typeof $().prop("checked")}`);
$holder.remove();
before=true,false
after=false,true
first getter=false; type=boolean
disabled count=2
empty getter=undefined

La lecture .prop("checked") renvoie seulement false pour le premier élément, tandis que la définition touche les deux. Pour tous les états, lisez chaque élément avec .map() ou .each(). Le premier élément décoché n’implique pas que tous le sont.

selectedIndex d’un select est aussi une propriété ; la première option a l’index zéro. .val() lit la valeur de l’option sélectionnée. Cet extrait de console choisit la deuxième option, affiche son index et sa valeur, puis supprime le contrôle temporaire.

const $select = $('<select><option value="a">Alpha</option><option value="b">Beta</option></select>').appendTo("body");
$select.prop("selectedIndex", 1);
console.log(`index=${$select.prop("selectedIndex")}; value=${$select.val()}`);
$select.remove();
index=1; value=b

Comprendre une valeur apparemment inchangée

Passez le booléen false à checked et disabled, pas la chaîne "false". Dans l’environnement vérifié, .prop("checked", "false") convertissait la chaîne en true et cochait la case. Définissez explicitement les états intégrés, par exemple .prop("disabled", false), plutôt que de supprimer ces propriétés.

Sur une sélection vide, la lecture renvoie undefined. Distinguez-le de false, qui est un état décoché valide. Si la cible devrait exister, vérifiez le sélecteur, .length et le moment où le DOM est prêt. Déterminez si vous voulez un attribut HTML ou une propriété DOM, sans mélanger les attributs data-* arbitraires avec l’état coché actuel.