Maison > Article > interface Web > Quand utiliser attr() et quand utiliser prop() dans jquery ?
Quelqu'un a donné plusieurs Le plug-in sélectionné a posé une question :
setSelects ne fonctionne pas dans Firefox lors de l'utilisation de jquery 1.9.0. J'utilise la version jQuery 1.8.3 et je n'ai pas essayé la version jQuery 1.9.0.
Alors, commencez à déboguer le code Dans la version 1.9.0 :
<input type="checkbox" /> <script> $(function() { $('input').click(function() { $(this).attr('checked'); }); }); </script>
Cliquez sur la case à cocher et les résultats sont tous indéfinis.
Dans la version 1.8.3, les résultats sont vérifiés et non définis
À ce stade, la réponse à la question est trouvée, ce qui est le problème de en utilisant la méthode attr(). J'ai donc vérifié la documentation officielle et découvert qu'à partir de jQuery 1.6, une nouvelle méthode prop() a été ajoutée, mais elle n'a jamais été utilisée.
Au sens chinois, ce sont des méthodes pour obtenir/définir respectivement des attributs et des propriétés, alors pourquoi devons-nous ajouter la méthode prop() ?Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior.Parce qu'avant jQuery 1.6, l'utilisation de attr() avait parfois un
comportement incohérent.
Alors, quand utiliser attr() et quand utiliser prop() ?To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method.Selon les recommandations officielles :
a deux attributs vrai et faux , tels que coché, sélectionné ou désactivé, utilisez prop(), d'autres utilisent attr().
À ce stade, remplacez attr('checked') par prop('checked') pour résoudre les problèmes mentionnés. Attendez, il semble que le problème n'ait pas encore été résolu. Pourquoi y a-t-il une différence entre jQuery 1.8.3 et 1.9.0 en utilisant attr() dans l'exemple du début ? Si vous voulez connaître la différence entre eux, le meilleur moyen est de regarder leur code source : 1.8.3 attr() :attr: function( elem, name, value, pass ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { return jQuery( elem )[ name ]( value ); } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, value + "" ); return value; } } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return ret === null ? undefined : ret; } }1.9 .0 attr( ) :
attr: function( elem, name, value, pass ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { return jQuery( elem )[ name ]( value ); } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // All attributes are lowercase // Grab necessary hook if one is defined if ( notxml ) { name = name.toLowerCase(); hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { elem.setAttribute( name, value + "" ); return value; } } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return ret === null ? undefined : ret; } }Le prop() de 1.8.3 et 1.9.0 est le même :
prop: function( elem, name, value ) { var ret, hooks, notxml, nType = elem.nodeType; // don't get/set properties on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { return ret; } else { return ( elem[ name ] = value ); } } else { if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { return ret; } else { return elem[ name ]; } } }
首先,我们看下 attr() 和 prop() 的区别:
attr() 里面,最关键的两行代码
elem.setAttribute( name, value + "" ); ret = elem.getAttribute( name );
很明显的看出来,使用的 DOM 的 API setAttribute() 和 getAttribute() 方法操作的属性元素节点。
prop() 里面,最关键的两行代码
return ( elem[ name ] = value );return elem[ name ];
可以理解为 document.getElementById(el)[name] = value,这是转化成 element 的一个属性。
对比调试 1.9.0 和 1.8.3 的 attr() 方法,发现两者的区别在于
hooks.get( elem, name ))
返回的值不一样,具体的实现:
1.8.3 中
boolHook = { get: function( elem, name ) { // Align boolean attributes with corresponding properties // Fall back to attribute presence where some booleans are not supported var attrNode, property = jQuery.prop( elem, name ); return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? name.toLowerCase() : undefined; } }
1.9.0 中
boolHook = { get: function( elem, name ) { var // Use .prop to determine if this attribute is understood as boolean prop = jQuery.prop( elem, name ), // Fetch it accordingly attr = typeof prop === "boolean" && elem.getAttribute( name ), detail = typeof prop === "boolean" ? getSetInput && getSetAttribute ? attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ? elem[ jQuery.camelCase( "default-" + name ) ] : !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); return detail && detail.value !== false ? name.toLowerCase() : undefined; } }
由此可见,1.9.0 开始不建议使用 attr() 来对具有 true 和 false 两个属性的属性进行操作了。
那么我们的结论是:
具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled 使用prop(),其他的使用 attr(),具体见下表:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!