Attribute operations mainly introduce the implementation of the three interfaces prop, attr, and val. Compared with other interfaces, these three source code implementations are complex and more confusing, if you accidentally use the wrong interface or return the wrong value, you should focus on the analysis.
9.1. prop () vs. attr ()
9.1.1 Overview
1.6.1 is the biggest improvement compared with 1.5.x. It is the rewriting of attribute. attr. In 1.6.1, Set. attr () is divided into two parts :. attr (),. prop () is a confusing change and a destructive upgrade that directly affects the upgrading of countless websites and projects to 1.6.
In short,. attr () is implemented through setAttribute and getAttribute, And. prop () is implemented through Element [name:
JQuery. attr
SetAttribute, getAttribute
JQuery. removeAttr
RemoveAttribute, removeAttributeNode (getAttributeNode)
JQuery. prop
Element [name]
JQuery. removeProp
Delete Element [name]
In fact, the difference between. attr () and. prop () is the difference between HTML attributes (HTML attributes) and DOM attributes (DOM properties. The HTML attribute parses the existing attributes in the HTML code and returns a string. The DOM attribute parses the attributes of the DOM object, which may be a string or an object, it may be the same or different from HTML attributes.
9.1.2 Test
Let's take a look at the example. We have an intuitive concept of the difference between HTML attributes and DOM attributes:
HTML code:
<A href = "abc.html" class = "csstest" style = "font-size: 30px;"> link </a>
<Input type = "text" value = "123">
<Input type = "checkbox" checked = "checked">
JavaScript code:
Console.info ($ ('# A'). attr ('href'); // abc.html
Console.info ($ ('# '). prop ('href '); // file: // H:/open/ws-nuysoft/com. jquery/abc.html
Console.info ($ ('# A'). attr ('class'); // csstest
Console.info ($ ('# A'). prop ('class'); // csstest
Console.info (document. getElementById ('A'). getAttribute ('class'); // csstest
Console.info (document. getElementById ('A'). className); // csstest
Console.info ($ ('# A'). attr ('style'); // font-size: 30px;
Console.info ($ ('# A'). prop ('style'); // CSSStyleDeclaration {0 = "font-size", fontSize = "30px ",...}
Console.info (document. getElementById ('A'). getAttribute ('style'); // font-size: 30px;
Console.info (document. getElementById ('A'). style); // CSSStyleDeclaration {0 = "font-size", fontSize = "30px ",...}
Console.info ($ ('# text'). attr ('value'); // 123
Console.info ($ ('# text'). prop ('value'); // 123
Lele.info ($ ('# checkbox'). attr ('checked'); // checked
Lele.info ($ ('# checkbox'). prop ('checked'); // true
We can see that the HTML attributes and DOM attributes are different in the attribute names and attribute values.
9.1.3 differences
The differences are summarized as follows:
The region attribute names may be different, although most of the attribute names are similar or consistent
The HTML property value always returns a string, and the DOM property value may be an integer, string, or object. You can get more information.
The initialize DOM attribute always returns the current status (value), while the initial status (value) returned by the HTML attribute (in most browsing cases)
The custom DOM attribute can only return the value of a fixed attribute name, while the HTML attribute can return the value of a custom attribute name in HTML code.
Compared with the browser compatibility of HTML attributes, the DOM attribute names and attribute values are slightly different between browsers, and DOM attributes are also subject to standards.
9.1.4 suggestions
Let's go back to. attr () and. prop (). After the above tests and analysis, we can get the following suggestions for using. attr () and. prop ():
Priority is given to. prop () Because. prop () always returns the latest status (value)
The. attr () method is used only when custom HTML attributes are involved. Alternatively, forget. attr ().
9.1.5 source code
Using jQuery. attr
// Set or obtain HTML attributes
// Http://stackoverflow.com/questions/5874652/prop-vs-attr
Attr: function (elem, name, value, pass ){
Var nType = elem. nodeType;
// Don't get/set attributes on text, comment and attribute nodes
// Ignore text, comments, and attribute nodes
If (! Elem | nType = 3 | nType = 8 | nType = 2 ){
Return undefined;
}
// If an attribute with the same name as the method is encountered, the method is executed.
// If you encounter extended attributes or attributes that need to be corrected, execute the corresponding method.
If (pass & name in jQuery. attrFn ){
Return jQuery (elem) [name] (value );
}
// Fallback to prop when attributes are not supported
// If getAttribute is not supported, jQuery. prop is called.
// Turn to prop? The prop is differentiated from attr and has to turn to prop. It seems that attr will be abandoned.
If (! ("GetAttribute" in elem )){
Return jQuery. prop (elem, name, value );
}
Var ret, hooks,
Notxml = nType! = 1 |! JQuery. isXMLDoc (elem );
// Normalize the name if needed
// Format name (corrected tabindex> tabIndex)
Name = notxml & jQuery. attrFix [name] | name;
// Property HOOK: type tabIndex
Hooks = jQuery. attrHooks [name];
// If no hook corresponding to name exists
If (! Hooks ){
// Use boolHook for boolean attributes
// Use a boolean hook to process a boolean attribute
If (rboolean. test (name )&&
(Typeof value = "boolean" | value = undefined | value. toLowerCase () = name. toLowerCase ())){
// Use a Boolean hook (static method object): set get
Hooks = boolHook;
// Use formHook for forms and if the name contains certain characters
// Use form hooks
} Else if (formHook & (jQuery. nodeName (elem, "form") | rinvalidChar. test (name ))){
// Use form hook (static method object): set get
Hooks = formHook;
}
}
// If the value has been defined, set or remove
// Set
If (value! = Undefined ){
// Typeof null === 'object' // true
// Typeof undefined === 'undefined' // true
// Null = undefined true
// Null === undefined false
// If the value is null, the name attribute is removed.
// Note that the constant number is used here.
If (value = null ){
JQuery. removeAttr (elem, name );
Return undefined;
}
// Attribute hook, Boolean hook, and form hook. If there is a corresponding Hook, the set Method of the hook is called.
Else if (hooks & "set" in hooks & notxml & (ret = hooks. set (elem, value, name ))! = Undefined ){
Return ret;
} Else {
// At the end, call setAttribute. All the hooks on the front are correction attributes.
// Forcibly convert value to string
Elem. setAttribute (name, "" + value );
Return value;
}
// If the value is undefined, it indicates that the property value is taken. If the corresponding Hook has a get method, the get method of the hook is called.
} Else if (hooks & "get" in hooks & notxml ){
Return hooks. get (elem, name );
} Else {
// Final: getAttribute
Ret = elem. getAttribute (name );
// Non-existent attributes return null, we normalize to undefined
// If the property does not exist, null is returned and the format is undefined.
Return ret = null?
Undefined:
Ret;
}
}
Using jQuery. prop
// Set or obtain DOM attributes
Prop: function (elem, name, value ){
Var nType = elem. nodeType;
// Don't get/set properties on text, comment and attribute nodes
// Ignore text, comments, and attribute nodes
If (! Elem | nType = 3 | nType = 8 | nType = 2 ){
Return undefined;
}
Var ret, hooks,
Notxml = nType! = 1 |! JQuery. isXMLDoc (elem );
// Try to normalize/fix the name
// Attribute name Modification
Name = notxml & jQuery. propFix [name] | name;
Hooks = jQuery. propHooks [name];
// Set
// Are you familiar with prop implementation? Well, it's similar to the idea of attr!
If (value! = Undefined ){
// If the set method exists in the hook, call the set Method of the hook.
If (hooks & "set" in hooks & (ret = hooks. set (elem, value, name ))! = Undefined ){
Return ret;
} Else {
Return (elem [name] = value );
}
// Read
} Else {
If (hooks & "get" in hooks & (ret = hooks. get (elem, name ))! = Undefined ){
Return ret;
} Else {
Return elem [name];
}
}
}
Using jQuery. fn. attr, jQuery. fn. prop
JQuery. attr and jQuery. prop are called internally through jQuery. access.
Attr: function (name, value ){
Return jQuery. access (this, name, value, true, jQuery. attr );
},
Prop: function (name, value ){
Return jQuery. access (this, name, value, true, jQuery. prop );
}
Using jQuery. access
// Mutifunctional method to get and set values to a collection
// The value/s can be optionally by executed if its a function
// A multi-function that reads or sets the property value of a set. If the value is a function, it is executed.
// Fn: jQuery.fn.css, jQuery. fn. attr, jQuery. fn. prop
Access: function (elems, key, value, exec, fn, pass ){
Var length = elems. length;
// Setting many butes
// Iteration if multiple attributes exist
If (typeof key = "object "){
For (var k in key ){
JQuery. access (elems, k, key [k], exec, fn, value );
}
Return elems;
}
// Setting one attribute
// Set only one attribute
If (value! = Undefined ){
// Optionally, function values get executed if exec is true
Exec =! Pass & exec & jQuery. isFunction (value );
// Call fn
For (var I = 0; I <length; I ++ ){
Fn (elems [I], key, exec? Value. call (elems [I], I, fn (elems [I], key): value, pass );
}
Return elems;
}
// Getting an attribute
// Read attributes
Return length? Fn (elems [0], key): undefined;
}
Author: nuysoft