Compared to attr, prop is new in 1.6.1. Both are understood from the Chinese meaning, and are methods to obtain/set attributes (attributes and properties). It's just that using the .attr() method in window or document cannot run normally before jQuery 1.6 because there cannot be attributes in window and document. Prop came into being.
Since we want to know the difference between them, it is best to look at their source code and not be scared by the length of the code. Let's only look at the key sentences:
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 return; } 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; } }prop method code (jQuery version 1.8.3)
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 ]; } } }In the attr method, the two most critical lines of code, elem.setAttribute( name, value + "" ) and ret = elem.getAttribute( name ), it is obvious that the DOM API setAttribute and getAttribute methods operated by the attribute element nodes.
In the prop method, the two most critical lines of code, return (elem[ name ] = value ) and return elem[ name ], you can understand it as document.getElementById(el)[name] = value, which is a property converted into a JS object.
Since we understand the principle, let’s take a look at an example:
<input type="checkbox" id="test" abc="111" />
$(function(){ el = $("#test"); console.log(el.attr("style")); //undefined console.log(el.prop("style")); //CSSStyleDeclaration object console.log(document.getElementById("test").style); //CSSStyleDeclaration object});el.attr("style") outputs undefined because attr is the value of the object attribute node obtained. Obviously, there is no attribute node at this time, so the natural output is undefined.
el.prop("style") outputs the CSStyleDeclaration object. For a DOM object, it has the native style object attribute, so the style object is output.
As for document.getElementById("test").style is the same as the above one
Next look:
el.attr("abc","111") console.log(el.attr("abc")); //111 console.log(el.prop("abc")); //undefinedFirst, use the attr method to add the abc node attribute to this object, with a value of 111, you can see that the structure of the html has also changed.
el.attr("abc") output is 111, which is normal
el.prop("abc") output undefined, because abc is in this property node, so it cannot be retrieved through prop.
el.prop("abc", "222"); console.log(el.attr("abc")); //111 console.log(el.prop("abc")); //222We then set the abc attribute for this object using the prop method, with a value of 222. You can see that the structure of the html has not changed. The output results will not be explained.
The above has explained the principle clearly, and you can grasp what you use yourself.
It is mentioned that when you encounter properties such as checked, selected, readonly and disabled, it is obviously better to use the prop method, such as the following:
<input type="checkbox" id="test" checked="checked" />
console.log(el.attr("checked")); //checked console.log(el.prop("checked")); //true console.log(el.attr("disabled")); //undefined console.log(el.prop("disabled")); //falseObviously, the Boolean value makes the next processing more reasonable than the string value.
PS. If you have JS performance cleanliness, obviously prop performance is higher, because attr needs to access DOM attribute nodes, accessing DOM is the most time-consuming. This situation applies to multiple options and unselected scenarios.
Everyone knows that some browsers only need to write disabled and checked, while others need to write disabled = "disabled", checked="checked". For example, when using attr("checked") to obtain the checked property of a checkbox, you can get the value when you select it. The value is "checked" but if you do not select it, it is undefined.
jq provides a new method "prop" to obtain these properties, which is to solve this problem. In the past, we used attr to obtain the checked property and returned "checked" and "", but now we use the prop method to obtain the properties and return true and false.
So, when to use attr() and when to use prop()?
1. Add the attribute name. This attribute will take effect. You should use prop();
2. There are two properties that have true and false use prop();
3. Use attr() for others;
Everyone should pay attention to this when upgrading jquery in the project!
The following are the official suggestions for the use of attr() and prop():
The following are the official suggestions for the use of attr() and prop():