jQuery / Méthode / .not() - Exclure des éléments d’une sélection

Dans jQuery, .not() renvoie un nouvel objet jQuery excluant les membres correspondants de la sélection actuelle. Elle ne retire pas ces éléments du modèle objet du document, DOM, et ne les masque pas automatiquement. Avec une fonction, les éléments renvoyant true sont exclus.

not exclut, filter conserve les correspondances

L'API .not() accepte chaînes de sélecteur, éléments/tableaux DOM, objets jQuery et fonctions. Chaque forme examine les membres d'une sélection existante, sans chercher de nouveaux descendants à l'intérieur.

Expression Membres conservés Retrait DOM
$all.not(".locked") Sans locked Non
$all.filter(".locked") Avec locked Non
$all.not(".locked, .featured") Aucune des deux conditions Non
$all.not(function) Test false Non

.filter() conserve les correspondances, à l'opposé de .not() pour le même test. Un booléen explicite rend la fonction plus claire. La nouvelle collection contient les références des nœuds existants, pas des copies ; .addClass() modifie donc les éléments réels.

Comparer exclusion et nombre dans le document

Enregistrez tout le code en UTF-8 dans not-demo.html et ouvrez-le dans un navigateur. Internet permet de charger le fichier officiel jQuery 4.0.0 depuis le réseau de diffusion de contenu, CDN, sans installation. Sélecteurs, fonctions, références, classes, ajout dynamique et Reset ont été exécutés avec 3.7.1 et 4.0.0.

Alpha est ordinaire, Beta locked, Gamma featured et Delta les deux. Seuls les membres conservés reçoivent picked ; les exclus restent visibles. source compte la collection initiale, kept le résultat et in DOM les éléments présents.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Exclude elements from a jQuery collection</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, select { font: inherit; margin: 4px; }
    li { padding: 8px; margin: 4px; border: 1px solid #aab; }
    .picked { background: #d9f4ef; border-color: teal; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Filter a collection without removing nodes</h1>
  <label for="mode">Exclude:</label>
  <select id="mode"><option value="locked">Locked class</option><option value="multi">Locked or featured</option><option value="callback">Even collection indices</option><option value="nodes">Beta and Delta node references</option></select>
  <button type="button" id="toggle">Toggle Alpha locked</button>
  <button type="button" id="add">Add Epsilon</button>
  <button type="button" id="reset">Reset</button>
  <ul id="items"><li id="alpha" data-name="Alpha">Alpha</li><li id="beta" class="locked" data-name="Beta">Beta (locked)</li><li id="gamma" class="featured" data-name="Gamma">Gamma (featured)</li><li id="delta" class="locked featured" data-name="Delta">Delta (locked, featured)</li></ul>
  <pre id="result" aria-live="polite"></pre>
  <script>
    $(function () {
      const initial = $("#items").html();
      function update() {
        const $all = $("#items > li");
        let $kept;
        switch ($("#mode").val()) {
          case "multi": $kept = $all.not(".locked, .featured"); break;
          case "callback": $kept = $all.not(function (index) { return index % 2 === 0; }); break;
          case "nodes": $kept = $all.not($("#beta, #delta")); break;
          default: $kept = $all.not(".locked");
        }
        $all.removeClass("picked");
        $kept.addClass("picked");
        const names = $kept.map(function () { return this.dataset.name; }).get();
        $("#result").text(`source=${$all.length} | kept=${$kept.length} | in DOM=${$("#items > li").length}\nkept=${names.join(", ")}`);
      }
      $("#mode").on("change", update);
      $("#toggle").on("click", function () { $("#alpha").toggleClass("locked"); update(); });
      $("#add").on("click", function () {
        if (!$("#epsilon").length) $('<li id="epsilon" data-name="Epsilon">Epsilon</li>').appendTo("#items");
        update();
      });
      $("#reset").on("click", function () { $("#items").html(initial); $("#mode").val("locked"); update(); });
      update();
    });
  </script>
</body>
</html>

Au départ, exclure locked conserve Alpha et Gamma :

source=4 | kept=2 | in DOM=4
kept=Alpha, Gamma
  1. Locked or featured met seulement Alpha en évidence. La virgule exclut toute correspondance à l'une des conditions.
  2. Even collection indices exclut 0 et 2, laissant Beta et Delta. Le premier élément a l'indice 0.
  3. Beta and Delta node references transmet ces nœuds réels dans un objet jQuery, laissant Alpha et Gamma.
  4. Revenez à Locked class et utilisez Toggle Alpha locked : seul Gamma reste mis en évidence. Répéter rétablit Alpha.
  5. Add Epsilon ajoute une entrée ordinaire une seule fois. Si Alpha est locked, Gamma/Epsilon restent et source/in DOM valent 5.
  6. Reset restaure les quatre éléments/classes et Locked class.

Indices de fonction et identité des nœuds

Dans .not(function(index, element)), index est la position depuis zéro dans la collection actuelle, pas forcément le rang parmi les enfants d'un parent. Dans une function classique, this et element désignent le nœud testé. True l'exclut : ne renvoyez pas par erreur la condition de ce que vous voulez garder.

Exécutez ce fragment complet dans la Console des outils de développement. Trois éléments i temporaires non insérés comparent not/filter, fonction et nœuds réels ou copies. Les dernières lignes les nettoient.

const $items = $('<i class="skip">A</i><i>B</i><i class="skip">C</i>');
console.log(`not=${$items.not(".skip").text()} | filter=${$items.filter(".skip").text()}`);
console.log(`source=${$items.length} | callback=${$items.not(function (index) { return index === 1; }).text()}`);
const $copy = $items.eq(1).clone();
console.log(`exclude same node=${$items.not($items.eq(1)).length} | exclude copy=${$items.not($copy).length}`);
$copy.remove();
$items.remove();
not=B | filter=AC
source=3 | callback=AC
exclude same node=2 | exclude copy=3

$items.length reste 3 après .not(). Exclure le deuxième nœud réel laisse deux éléments ; passer son clone visuellement identique laisse les trois, car c'est un autre objet. Pour des références externes, vérifiez le nœud réel plutôt qu'une similarité de sélecteur ou de balisage.

Portée du sélecteur et changements d'état

Une condition simple peut aussi utiliser le sélecteur :not(). #items > li:not(.locked) exclut locked dans la même portée li. Avec plusieurs conditions, références ou fonctions, définir la collection de base puis séparer les .not() peut être plus lisible.

.not(".locked, .featured") exclut l'une ou l'autre classe ; .not(".locked.featured") seulement les éléments ayant les deux. Sans point, locked est un nom de balise. Une condition visant le span enfant n'exclut pas automatiquement le li parent : distinguez membres testés et descendants.

Le résultat n'est pas une liste vivante. update() resélectionne les li et refiltre à chaque fois, intégrant Epsilon et les changements de classe. Une collection conservée ne suit pas automatiquement le document. Même vide, elle reste un objet jQuery : vérifiez .length et définissez séparément l'action si une suppression réelle est voulue.