jQuery / Método / .not() - Excluir elementos de una selección
En jQuery, .not() devuelve un objeto jQuery nuevo que excluye miembros coincidentes de la selección actual. No los retira del modelo de objetos del documento, DOM, ni los oculta automáticamente. Con una función, se excluyen los elementos que devuelven true.
not excluye y filter conserva coincidencias
La API .not() acepta cadenas de selector, elementos/arrays DOM, objetos jQuery y funciones. Todas examinan miembros de una selección existente; no buscan nuevos descendientes dentro de ellos.
| Expresión | Miembros conservados | Eliminación DOM |
|---|---|---|
| $all.not(".locked") | Sin locked | No |
| $all.filter(".locked") | Con locked | No |
| $all.not(".locked, .featured") | Ninguna de las dos condiciones | No |
| $all.not(function) | Prueba false | No |
.filter() conserva coincidencias, al contrario que .not() para la misma prueba. Un booleano explícito aclara la función. La colección nueva contiene referencias a nodos existentes, no copias; .addClass() cambia esos elementos reales.
Comparar exclusión y cantidad en el documento
Guarda el código completo en UTF-8 como not-demo.html y ábrelo en el navegador. Necesitas internet para cargar el archivo oficial de jQuery 4.0.0 desde su red de distribución de contenidos, CDN, sin instalación. Selectores, funciones, referencias, clases, adición dinámica y Reset se ejecutaron con 3.7.1 y 4.0.0.
Alpha es normal, Beta locked, Gamma featured y Delta ambos. Solo los conservados reciben picked; los excluidos siguen visibles. source cuenta la colección original, kept el resultado e in DOM los elementos presentes.
<!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>
Inicialmente excluir locked conserva Alpha y Gamma:
source=4 | kept=2 | in DOM=4
kept=Alpha, Gamma
- Locked or featured resalta solo Alpha. La coma excluye lo que coincida con cualquiera de las condiciones.
- Even collection indices excluye 0 y 2, dejando Beta y Delta. El primero tiene índice 0.
- Beta and Delta node references pasa esos nodos reales en un objeto jQuery, dejando Alpha y Gamma.
- Vuelve a Locked class y pulsa Toggle Alpha locked: queda solo Gamma resaltado. Repetir devuelve Alpha.
- Add Epsilon añade una entrada normal una vez. Con Alpha locked quedan Gamma/Epsilon y source/in DOM son 5.
- Reset restaura los cuatro elementos/clases y Locked class.
Índices de función e identidad del nodo
En .not(function(index, element)), index es la posición desde cero de la colección actual, no necesariamente el orden de hermanos en un padre. En una function normal, this y element son el nodo evaluado. True lo excluye; no devuelvas por error la condición de los que querías conservar.
Ejecuta este fragmento completo en Console de las herramientas de desarrollo. Tres elementos i temporales no insertados comparan not/filter, función y nodos reales frente a copias. Las últimas líneas los limpian.
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 permanece en 3 después de .not(). Excluir el segundo nodo real deja dos; pasar su clone visualmente igual deja los tres porque es otro objeto. En referencias externas, comprueba el nodo real y no la similitud de selectores o marcado.
Ámbito del selector y cambios de estado
Una condición simple también puede usar el selector :not(). #items > li:not(.locked) excluye locked en el mismo ámbito li. Con condiciones, referencias o funciones variadas, definir primero la colección y separar .not() puede ser más legible.
.not(".locked, .featured") excluye cualquiera; .not(".locked.featured") solo elementos con ambas clases. Sin punto, locked es una etiqueta. Una condición sobre el span hijo no excluye automáticamente su li padre: distingue miembros evaluados y descendientes.
El resultado no es una lista viva. update() selecciona li y vuelve a excluir en cada ejecución, reflejando Epsilon y clases nuevas. Los resultados guardados no siguen automáticamente los cambios del documento. Incluso vacío sigue siendo objeto jQuery: comprueba .length y define por separado la acción si necesitas eliminar realmente.




