Compared with attr, prop is new only after 1.6.1. Both of them are based on Chinese meaning and are used to obtain/set attributes (attributes and properties ). However, the. attr () method used in window or document cannot run normally before jQuery1.6, because attributes cannot exist in window and document. Prop came into being.
Since we want to know the differences between them, it is best to look at their source code. Don't be scared by the code length. Let's just look at the key words:
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; } }
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 are elem. setAttribute (name, value + "") and ret = elem. getAttribute (name), it is obvious that the attribute element nodes operated by the dom api setAttribute and getAttribute are used.
In the prop method, the two most critical lines of code are return (elem [name] = value) and return elem [name], which can be understood as document. getElementById (el) [name] = value, which is an attribute converted to a JS object.
Now that we understand the principle, let's 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 property node of this object obtained. Obviously, this property node is not available at this time, and undefined is naturally output.
El. prop ("style") outputs the CSSStyleDeclaration 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
Next, let's see:
el.attr("abc","111") console.log(el.attr("abc")); //111 console.log(el.prop("abc")); //undefined
First, use the attr method to add the abc node attribute to this object. The value is 111. You can see that the html structure has changed.
El. attr ("abc") Outputs 111, which is not enough.
El. prop ("abc") Outputs undefined. Because abc is in this attribute node, it cannot be obtained through prop.
el.prop("abc", "222"); console.log(el.attr("abc")); //111 console.log(el.prop("abc")); //222
We use the prop method to set the abc attribute for this object. The value is 222. We can see that the structure of html is not changed. The output result is not explained.
The principle has been clearly explained above, and you can grasp the principle at any time.
It is better to use the prop method to obtain or set attributes such as checked, selected, readonly, and disabled, as shown below:
<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")); //false
Obviously, the Boolean value makes the subsequent processing more reasonable than the string value.
PS: If you have JS performance cleanliness, it is obvious that prop has higher performance, because attr needs to access DOM attribute nodes, and DOM access is the most time-consuming. This situation applies to the case where multiple options are all selected and multiple options are selected.
We all know that some browsers only need to write disabled and checked, while some need to write disabled = "disabled", checked = "checked", such as attr ("checked ") you can obtain the value when you select the checked attribute of the checkbox. The value is "checked", but the undefined value is not selected.
Jq provides a new method "prop" to obtain these attributes to solve this problem. In the past, when we used attr to obtain the checked attribute, we returned "checked" and "", if you use the prop method to obtain attributes, both true and false are returned.
So when will attr () and prop () be used ()?
1. Add a property name. This property will take effect. Use prop ();
2. There are true and false attributes using prop ();
3. For others, use attr ();
Pay attention to this when upgrading jquery in the project!
We recommend that you use attr () and prop () as follows:
We recommend that you use attr () and prop () as follows: