jQuery / Método / .prop() - Leer y establecer propiedades DOM
En jQuery, .prop("nombre") lee una propiedad DOM del primer elemento seleccionado y .prop("nombre", valor) la establece en todos. Use .prop("checked") para el estado marcado actual y .prop("disabled") para el estado deshabilitado. Distinga las propiedades actuales del navegador de las cadenas de atributos HTML.
Estado actual y atributos HTML
El modelo de objetos del documento (DOM) representa HTML mediante nodos y objetos. checked, disabled y selectedIndex son propiedades de esos objetos en la API de .prop(). .attr() lee y establece atributos HTML. Compartir nombre no siempre significa compartir el estado actual.
| Pregunta | Método | Significado |
|---|---|---|
| ¿Está marcado ahora? | .prop("checked") | Booleano true/false actual |
| ¿Marcado por defecto? | .prop("defaultChecked") | Valor predeterminado asociado al atributo checked |
| ¿Atributo HTML? | .attr("checked") o getAttribute("checked") | No cambia automáticamente con los clics |
| ¿Valor del control? | .val() | value o valor seleccionado, separado del estado marcado |
<input type="checkbox" checked=""> empieza marcado. Desmarcarlo cambia checked a false sin cambiar defaultChecked ni el atributo. El atributo checked de la casilla es booleano: importa su presencia. checked="false" no significa desmarcado.
No use la cadena .attr("checked") para decidir el estado actual. Con checked="" aquí, 3.7.1 devolvió "checked" y 4.0.0 la cadena vacía "". Una cadena vacía es falsa en una condición JavaScript aunque la casilla esté marcada. Lea el booleano .prop("checked") en vez de comparar cadenas dependientes de la versión.
Ejemplo completo de estados y eventos change
Guarde todo el código en UTF-8 como prop-demo.html y ábralo en el navegador. Se necesita Internet para cargar el archivo oficial de jQuery 4.0.0 desde la red de distribución de contenido (CDN), sin instalación. Las interacciones y los fragmentos de consola se ejecutaron con 3.7.1 y 4.0.0. getAttribute() nativo muestra el atributo igual en ambas versiones.
<!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>
Esta es la salida inicial. Las dos comillas tras checked attribute indican que el atributo existe con valor vacío. Si no existiera, getAttribute() devolvería null.
checked=true
defaultChecked=true
checked attribute=""
disabled=false
value=weekly
change events=0
- Toggle checked cambia checked a false conservando el valor predeterminado, el atributo y value. change events sigue en cero.
- Marque directamente la casilla: change events aumenta uno. Compare por separado cambio de estado y notificación.
- Set unchecked and disabled aplica .prop({ checked: false, disabled: true }). La casilla queda desmarcada y no puede manejarse directamente.
- Enable pone disabled en false sin marcar la casilla.
- Check and trigger change pone checked en true y dispara change explícitamente. El contador aumenta; asignar solo la propiedad no ejecuta el controlador.
- Reset restaura el estado marcado predeterminado, quita disabled por separado y pone el contador en cero. Repetirlo devuelve la misma salida inicial.
No suponga que reset() restaura también disabled: el ejemplo lo quita expresamente. Disparar change avisa a controladores registrados, sin reproducir toda una interacción física del puntero. Si solo necesita actualizar la pantalla tras cambiar una propiedad desde código, llame directamente a una función como report().
Objetos, funciones y selectedIndex
Use un objeto para varias propiedades y una función para valores por elemento. La función recibe el índice desde cero y el valor anterior; lo que devuelve será el valor nuevo. Tras Reset, ejecute este fragmento completo en la consola de las herramientas de desarrollo. Crea dos casillas temporales, invierte sus estados, las deshabilita y las elimina al terminar.
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 consulta .prop("checked") devuelve solo false del primer elemento, pero la asignación afecta a los dos. Para todos los estados, lea cada elemento con .map() o .each(). Que el primero esté desmarcado no significa que todos lo estén.
selectedIndex de un select también es una propiedad: la primera opción tiene índice cero. .val() lee el valor de la opción seleccionada. Este fragmento elige la segunda opción, muestra índice y valor y elimina el control temporal.
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
Investigar valores aparentemente sin cambios
Pase el booleano false a checked y disabled, no la cadena "false". En el entorno verificado, .prop("checked", "false") convirtió la cadena en true y marcó la casilla. Establezca los estados incorporados explícitamente, por ejemplo .prop("disabled", false), en lugar de eliminar esas propiedades.
La consulta sobre una selección vacía devuelve undefined. Distíngalo de false, un estado desmarcado válido. Si debería existir la referencia, revise el selector, .length y el momento de preparación del DOM. Decida si necesita un atributo HTML o una propiedad DOM; no mezcle atributos data-* arbitrarios con el estado checked actual.




