Compared with attr, prop is new in 1.6.1. Both of them are understood from the Chinese meaning, and they are both methods of getting/setting attributes (attributes and properties). However, the .attr() method used in window or document cannot run properly before jQuery 1.6, because there cannot be attributes in window or document. prop came into being.
Since we want to know the difference between them, it’s best to look at their source code. Don’t be scared by the length of the code. Let’s just look at a few 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 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 DOM API setAttribute and getAttribute method operations are used. attribute element node.
In the prop method, the two most critical lines of code are return (elem[ name ] = value ) and return elem[ name ]. You can understand it like this: document.getElementById(el)[name] = value, which is converted into JS A property of the object.
Now that 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对象 console.log(document.getElementById("test").style); //CSSStyleDeclaration对象 });
el.attr("style") outputs undefined, because attr is the value of the attribute node of this object obtained. Obviously there is no such attribute node at this time, so it naturally outputs undefined
el.prop("style") outputs a CSSStyleDeclaration object. For a DOM object, it has native style object attributes, so the style object
is output
As for document.getElementById("test").style is the same as the one above
Read on:
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, with a value of 111. You can see that the structure of the html has also changed
The output result of el.attr("abc") is 111, which is normal
el.prop("abc") outputs undefined, because abc is in this attribute node, so it cannot be obtained through prop
el.prop("abc", "222"); console.log(el.attr("abc")); //111 console.log(el.prop("abc")); //222
We then use the prop method to set the abc attribute for this object, with a value of 222. You can see that the structure of the html has not changed. The output results are not explained.
The principle has been explained clearly above, you can decide by yourself when to use it.
Mention that when you want to get or set 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")); //false
Obviously, boolean values make the following processing more reasonable than string values.
PS, if you are obsessed with JS performance, obviously the performance of prop is higher, because attr needs to access the DOM attribute node, and accessing the DOM is the most time-consuming. This situation applies to multi-option all-select and inverse-select situations.
Everyone knows that some browsers only need to write disabled and checked, while others need to write disabled = "disabled", checked="checked", such as when using attr("checked") to get the checked attribute of checkbox The value can be obtained when it is selected. The value is "checked" but the value obtained when it is not selected is undefined.
jq provides a new method "prop" to get these attributes to solve this problem. In the past, when we used attr to get the checked attribute, we returned "checked" and "". Now, when we use the prop method to get the attribute, we uniformly return true and false.
So, when to use attr() and when to use prop()?
1. Add the attribute name and the attribute will take effect. You should use prop();
2. There are two attributes, true and false, using prop();
3. For others, use attr();
Everyone should pay attention to this when upgrading jquery in the project!
The following are official recommendations for the use of attr() and prop():
The following are official recommendations for the use of attr() and prop():