Apenas unos días después de la salida de jQuery 1.6, el equipo de John Resig se ha visto obligado a lanzar una nueva versión (la 1.6.1) para corregir los problemas de retrocompatibilidad que estaba ocasionando el rediseño de los métodos .attr() y .prop().
El problema venía en cómo la biblioteca asignaba de forma interna valores de elementos DOM alterando el comportamiento de versiones anteriores.Tomemos por ejemplo el siguiente código:
<input id="mychkbox" type="checkbox" checked /> |
Este marcado es correcto desde el punto de vista HTML pero, al no existir un criterio de igualdad (checked=»checked»), jQuery 1.6 asignaba al atributo una cadena vacía:
// jQuery 1.6 console.log( $("#mychkbox").attr("checked")) // "" console.log( $("#mychkbox").prop("checked")) // true console.log( document.getElementById("mychkbox").checked") // true |
Esto es así porque, como vimos en su momento, el atributo no cambia cuando el usuario hace click sobre el elemento modificando su estado (ese cambio solo tiene que reflejarse en su propiedad). Pero .attr(), al no reflejar el estado inicial, está funcionando de forma diferente a como lo hacía en versiones anteriores y creando por tanto inconsistencias.
Con la actualización a 1.6.1, tenemos lo siguiente:
// jQuery 1.6.1 console.log( $("#mychkbox").attr("checked")) // true console.log( $("#mychkbox").prop("checked")) // true console.log( document.getElementById("mychkbox").checked") // true |
Ahora, el comportamiento de attr es similar a las versiones anteriores con lo que obtenemos la retrocompatibilidad que los usuarios han demandado en los últimos días.
Para evitar confusiones, desde la documentación oficial se recomienda usar el método prop en aquellos valores booleanos dentro de un elemento (ya sean atributos o propiedades) y en propiedades que no existen en el marcado HTML (como por ejemplo un window.location). El resto de atributos pueden –y deberían– continuar siendo manipulados con el método attr.
La siguiente tabla muestra un resúmen de casos de uso:
.attr() | .prop() |
---|---|
accesskey | async |
align | autofocus |
class | checked |
contenteditable | location |
draggable | multiple |
href | readOnly |
id | selected |
label | |
rel | |
src | |
tabindex | |
title | |
type | |
width |
Conclusión
En definitiva, se trata de una actualización importante porque redefine el comportamiento de un controlador anterior susceptible de generar errores bajo distintas versiones de la popular biblioteca.
De nuevo, el equipo jQuery demuestra que está completamente abierto a sugerencias por parte de su comunidad y a reaccionar casi de inmediato frente a meteduras de pata como esta.
La verdad es que me alegro de que hayan dado un poco de marcha atrás en este tema. A mi modo de ver, cambiar a esta altura la forma de usar el método .attr() era un poco locura, más que nada porque en muchos proyectos iba a haber un montón de bugs si decidieran cambiar alegremente a la v1.6.
Un saludo!