JS magic Hall: unclear about attributes and features
I. Preface you may have been troubled by the following code like me: var el = document. getElementById ('dummy'); el. hello = "test"; console. log (el. getAttribute ('hello'); // test is output in IE67, and null is output in other browsers? ", The hard-pressed Jser shouted at the browser. Then we can use the following method to handle it. Copy the code function getAttr (el, prop) {return el [prop] | el. getAttribute (prop);} // function setAttr (el, prop, val) {el [prop] = val ;} // The corresponding clearing function removeAttr (el, prop) {delete el [prop];} although it is done to copy the code, what is Property )? What is Attribute )? It's still silly. I had the honor to read situ zhengmei's book and finally understood the difference between the two. The following content is not easy for the content and projects in the book! 2. Understand From the semantics that both Property and Attribute are foreign words. First, let's look at what they translate first! Property: Attribute, ownership, feature Attribute of the subject object: Attribute, feature, feature of the subject object, feature of other objects from the above semantic inference, Attribute should be a subset of Property. Unfortunately, browsers do not understand this, even if they comply with W3C standards. 3. W3C defines the meaning of Property and Attribute to see if the graph is healthier. We can see that the "Attribute" of the element is divided into three parts: 1. standard attribute: standard attributes (or inherent attributes), such as the tag attributes defined in DTD/Scheme, such as id and name. Features: You can access and set the node or getAttribute. 2. custom property: custom attribute. The tag attribute defined in non-DTD/Scheme accessed and set in the dot mode. Feature: You can operate properties only by clicking. 3. custom attribute: custom features (explicit features) that are directly written in tags or defined in non-DTD/Scheme accessed and set by getAttribute and other APIs. Features: ①. explicit declarations can be made in html tags, such as <div customAttr = "attrValue"> </div> ②. use getAttribute and other APIs to operate attributes. Since IE8, the major browsers have followed W3C standards in this respect, so there is a problem with the compatibility of code snippets in the preface. Iv. M attribute type-[object Attr] I 'd like to know about the [object Attr] type, which will be helpful for understanding the subsequent content, so I am sorry to interrupt it here. The attribute object type of custom attribute is [object Attr]. Browser support: IE8 + (IE567 provides APIs of the same type as [object Attr] in the form of [Object object]), FF, and Chrome features: ①. although Attr is regarded as a node, it is not part of the DOM tree. Therefore, it does not have a parent node or a child node of the html node. ②. the value of the Attr node is a string (except IE567). Therefore, if a value of Non-string type is assigned by setAttribute, implicit type conversion is performed. Property Value: property name value or function description nodeType 2 nodeName property name nodeValue {Text} property value parentNode nullchildNodes IE8 return null; IE9 + and Chrome return the NodeList object with the attribute value (the attribute value type is [object Text]) as the element; FF30.0 returns the null NodeList. Name and nodeName consistent value and nodeValue consistent textContent setting or return attribute text content specified is used to determine whether the attribute value is a custom value, true indicates that it is customized in the document; false indicates the default value set by DTD/Scheme. Create: document. createAttribute ({String} attribute name): 123HTMLElement object. setAttributeNode ({Attr} attr); HTMLElement object. getAttributeNode ({String} attribute name); HTMLElement object. removeAttributeNode ({Attr} attr); // return the deleted Attr node. Note: HTMLElement object. removeAttributeNode ({Attr} attr). When the HTMLElement object does not have the attr attribute, an exception (NotFoundError: Failed to execute 'removeattributenode 'on 'Element ': the node provided is owned by another eleme Nt .) indirect operation: 1234HTMLElement object. setAttribute ({String} attribute name, {Any} attribute value); HTMLElement object. getAttribute ({String} attribute name); HTMLElement object. removeAttribute ({String} attribute name); HTMLElement object. hasAttribute ({String} attribute name); // IE8 + is used to determine whether an element has this feature. Note: HTMLElement object. removeAttribute ({String} attribute name). When the HTMLElement object does not have an attribute with a specified attribute name, it adopts the silent mode (that is, if the object is successfully deleted, undefined is returned) v. Point Method -- exclusive operation method of custom property var el = document. getElementById ('dummy'); el. id; // Point mode el ['hello'] = 'test'; // point mode 6. standard attribute can be accessed through point mode and getAttribute, but what are standard attributes? The following describes two methods to judge. ①. Check http://msdn.microsoft.com/library/ms533029%28v=VS.85%29.aspx ②. the idea provided by situ zhengmei (the cache should be added in the production environment to improve the performance) is to copy the code // IE5 +, Chrome, FF are all effective functions isStandardAttr (node, prop) {// because window and document do not have the getAttribute method, false is returned for the moment. if (! Node. getAttribute) return false; var nakedNode = document. createElement (node. nodeName); return! (NakeNode [prop] === void 0 & nakeNode. getAttribute (prop) = null);} when the non-standard attribute of the copied code is not assigned a value, undefine is returned for point-based access, and null is returned for getAttribute access. When the standard attribute is not assigned a value, the default value of the attribute will be returned for point-based access (title, id, etc. will return an empty string, while checked will return false), and The getAttribute method will return null. Not conducive to judgment. Therefore, the previous paragraph is used for judgment. 7. For standard attribute, the difference between Dot-based and getAttribute-based operations must be clarified first. You can assign values to attribute values of any js Data Type through dot-based operations, if you assign a value using setAttribute, the input parameter is automatically serialized and assigned to the attribute. Therefore, JavaScript data types are operated in the dot mode, while getAttribute and other methods operate on the attribute values of the string type. Difference 1: The obtained attribute values are different: the point-based access is the result of the calculation of the attribute values, while the getAttribute method accesses the static attribute values. Take the href attribute as an example. File: c: \ test.html, html Tag: <a href = "$ {link 1}" ></a>: the browser points the getAttribute result to IE8 + absolute path. The symbol is encoded and the Chinese character is not encoded. file: // c: /$ % 7B link 1% 7D original attribute value $ {link 1} Chrome, FF absolute path, symbol encoded, Chinese encoded file: // c: /$ % 7B % E9 % 93% BE % E6 % 8E % A51 % 7D "original attribute value $ {link 1} difference 2. attribute names are different: for some standard attributes, for the same attribute, different attribute names are used for vertices and getAttribute operations. Point-based getAttributeclassName classhtmlFor forstyle.css Text style 8. Confusing focus-standard property because standard property can be operated by point-based and getAttribute-based, relative to the other two attributes, standard property is the most complex. Next I will subdivided it into ①. The point method of common attributes (such as id and name) is the same as that of getAttribute, and the attribute value is automatically converted to the String type. ②. The dom.style.css Text of the style attribute corresponds to the dom. getAttribute ('style') operation, both of which are values of the String type. When a normal style rule is granted, all browser behaviors are consistent. However, the complexity is when an abnormal style rule is assigned, the behavior of Each browser is as follows: value assignment method: getAttribute access: browser access: null String: null Chrome; FFsetAttriubte: null String: null IE9setAttribute: null String: Point Method: null String: IE8, 10, 11 setAttribute empty string Note: Under the IE8-11, when an exception style rule is set through setAttribute, the style attribute in the html Tag will be deleted, therefore, you cannot extract the string value of an exception style rule using outerHTML. ③. Boolean attributes (such as checked, disabled, and selected) are also Boolean attributes during tossing, but the features are different. Therefore, the following categories are provided temporarily. 3.1. general Boolean attributes (such as checked under disabled and IE5678) value assignment method: value-Point Access: getAttribute access: true Null String false nullsetAttribute Null String true Null String any non-disabled string true IE9 +, Chrome and FF are returned setAttribute settings value; IE8 is CHECKED removeAttribute false null is set in setAttribute mode. Only the Boolean attribute name is displayed, and the Boolean attribute value is true. The operation results are synchronized between the two methods. 3.2. The Boolean attribute of non-removeAttr (such as selected) does not know what the name is, so I have to call it for the time being. Its behavior is similar to common Boolean properties except that the removeAttribute operation cannot change the attribute value obtained by the point method. Specifically, the SELECT element belongs to the single-choice mode. When the selected attribute is operated in the dot mode, true indicates selected, false indicates not selected, and setAttribute indicates selected, true is returned when selected is accessed in the dot mode. However, after the selected attribute is removed through removeAttribute, the selected item is not changed because selectedIndex is not changed. Inference: After the option label sets the selected explicit attribute, it will change the value of selectedIndex to change the selected item. In removeAttribute, only this attribute is removed, but the value of selectedIndex is not changed, therefore, the selected items are not changed. The point method is to obtain whether the project is selected based on selectedIndex. SELECT element multi-choice mode: true indicates selected when the selected attribute is operated in the dot mode, false indicates not selected, and true indicates selected when the selected attribute is accessed in the dot mode; however, after the selected attribute is removed through removeAttribute, the selected item is not changed. 3.3. mutating Boolean attributes (such as IE9 +, Chrome, and FF checked) The biggest feature of mutating Boolean attributes is that before the user UI modifies the attribute values and changes the attribute values by point, the point method and getAttribute method operate on the same attribute. However, after the user UI or the point method changes the attribute value, the two operations are two attributes with the same name. In this case, the point operation is the attribute associated with the UI status. The Code is as follows: the checked attribute of the CHECKBOX and RADIO elements in IE9 +, Chrome, and FF belongs to the variant Boolean attribute, while the checked attribute in IE5678 belongs to the bidirectional Boolean attribute. Copy the code var cbx = document. createElement ('input'); cbx. type = 'checkbox'; // The cbx before modifying attributes in UI or dot mode. setAttribute ('checked', ''); console. log (cbx. checked); // returns truecbx. removeAttribute ('checked'); console. log (cbx. checked); // return false // cbx after modifying the attribute in the dot mode. checked = true; console. log (cbx. checked); // returns trueconsole. log (cbx. getAttribute ('checked'); // return null cbx. checked = false; console. log (cbx. checked); // returns falsecbx. setAt Trigger ('checked', ''); console. log (cbx. checked); // return false copy code ④. event hooks (such as onclick) are the DOM0-level event subscription method, which is usually not used now, but does not prevent us from tossing. The result is surprising, because it is different from the features of standard attribute, that is, point-based and getAttribute-based operations have one-way impact. For details, see the code (IE8-11, Chrome, FF): copy the code var dom = document. createElement ('div '); dom. setAttribute ('onclick', 'console. log ("bySA"); ');/* output * function onclick () {* console. log ("bySA"); *} */console. log (dom. onclick);/* output * console. log ("bySA"); */console. log (dom. getAttribute ('onclick'); dom. onclick = function () {console. log ('byprop') ;};/* output * dom. onclick = function () {* console. log ('byprop'); *}; */co Nsole. log (dom. onclick);/* output * console. log ("bySA"); */console. log (dom. getAttribute ('onclick'); // output byPorpdom. click (); copy the Code. In general, the event hook mode set in setAttribute mode is visible, and the event hook getAttribute set in click mode is invisible. ⑤. JQuery has used the value attribute to know how comfortable a val function is to deal with a wide variety of form elements. But what are the pitfalls of native value attributes? Let's step on it now. 5.1. The SELECT label drop-down box has two modes: select-one and select-multiple. The value attribute is the calculation result of the property value and the text attribute of the selected item. Therefore, it is recommended that you use the dot operation. The operation flow for getting and setting value values in the dot mode is as follows: the browser operation flow selectedIndex defaults to Chrome and FF to get the value attribute of the first selected option. If the value attribute is not set, the text attribute of the option label is returned. single choice: 0 Multiple choices:-1 is set to match the value attribute value of the option label based on the attribute value. If the matching succeeds, the option is selected; if it fails, the text attribute value of option is matched. If yes, selectedIndex is set to-1. When the value is accessed through the dot method again, an empty string is returned. IE9 + gets the value Attribute of the first selected option. If the value attribute is not set, the text attribute of the option label is returned. single choice: 0 Multiple choices: -1 is set to match the value attribute value of the option label based on the attribute value. If the matching succeeds, the option is selected. If the matching fails, selectedIndex is set to-1. When the value is accessed through the dot method again, an empty string is returned. IE5678 obtains the value Attribute of the first selected option. If the value attribute is not set, an empty string is returned. Single-choice and multiple-choice:-1 matches the value Attribute value of the option label based on the attribute value. If the matching succeeds, the option is selected. If the matching fails, selectedIndex is set to-1. When the value is accessed through the dot method again, an empty string is returned. Text attribute: the property value is the string returned by innerText. trim () of the selected item. Conclusion: It is unreliable to obtain the value of the selected item through the value attribute of the SELECT element. Therefore, the value of the mass framework in valHooks ['@ select: get '] obtains the value of the selected item by operating the OPTION element. Because the disabled attribute value of the SELECT element or OPTION element is true, the selected Attribute of the OPTION element may still return true, therefore, you must filter out the unavailable OPTION elements. 5.2. the value Attribute of the CHECKBOX and RADIO labels defaults to the string "on" 6. the attribute value obtained by the Url attribute (such as href and src) is an absolute path and the special characters and Chinese characters are encoded. The original value obtained by the getAttribute method is used. I think everyone is nodding and dizzy here. It will be better to sum up! 1. you can use either of the following methods for common attributes: 2. we recommend that you operate style, Boolean, and event hook attributes in the dot mode. 3. for the value attribute, do not use JQuery and other dom libraries for unified operations, or perform specific operations on specific elements. The valHooks ['@ select: get'] is used to traverse the option element to obtain the selected value of the select statement. 4. the Url attribute depends on the specific requirements. If you want to obtain the absolute path, use the dot method. Otherwise, use getAttribute! 9. attribute classification of window and document objects because neither window nor document Object has the getAttribute function, we can see that there must be no custom attribute. However, we can still divide their attributes into inherent and custom attributes. Inherent attributes: The member attributes and methods carried by the window and document objects. Features: ①. You cannot delete the inherent attributes through the delete operation. Exceptions may occur in IE5.5, 6, and 7! ②. The inherent attribute is a read-only attribute and cannot be modified. Custom Attributes: attributes and methods that Jser attaches to the window and document objects. Features: ① can be deleted through the delete operation; ②. Custom Attributes can be changed at will. Next, I will combine the judgment of inherent attributes with the method for judging standard attributes in Section 6 of this Article: copying code // IE5 +, Chrome, and FF are all effective functions isStandardAttr (node, prop) {// because window and document do not have the getAttribute method, the if (! Node. getAttribute) {var oVal = node [prop], nVal; nVal = node [prop] = + new Date (); node [prop] = oVal; return nVal = oVal;} var nakedNode = document. createElement (node. nodeName); return! (NakeNode [prop] === void 0 & nakeNode. getAttribute (prop) = null);} copy the features and attributes of code 10, IE5.5, 6, and 7. Both M property and custom attribute are classified by IE8 +, in IE5.5, 6, and 7, the two are in a group. In IE7, dom. getAttribute ('style') is an object rather than a string of style rules. Maybe you will think this is not in the way of the problem. You can just use the dot method to obtain the style attribute. However, if you do not pay attention to the following situations, the bug will occur. Scenario 1: Call the getAttribute of the form element to obtain the action attribute and obtain the FORM element under it? Html copy Code <form action = ". /add. aspx "name =" frm "id =" frm "> <input type =" text "id =" name "/> <input type =" text "name =" id "/> <select id = "action"> <option value = "0"> all </option> </select> </form> copy code js and copy code var fDom = document. getElementById ('frm'); var action = fDom. getAttribute ('action'); var name = fDom. geAttribute ('name'); var id = fDom. geAttribute ('id'); console. log (typeof action); // return to objectconsole. log (Action. id); // Return action console. log (typeof name); // return to objectconsole. log (name. id); // return name console. log (typeof id); // return to objectconsole. log (id. name); // The id copy code returned may be confusing. At most, this is to get the attribute value of the FORM element through the dot method. Why do we get the FORM element with the matching id or name attribute value? If you have read the JS magic Hall: DOM collections that plague you, you will know that the FORM element has an elements attribute of the HTMLFormControllersCollection type, this attribute can be used to obtain the FORM element that matches the id or name attribute values under the FORM element by clicking. The FORM element has the features of elements directly. Therefore, in addition to getting the attribute values of the FORM element, you can also access the FORM elements. Solution: Use getAttributeNode to obtain the Attr object copy code var actionNode = fDom. getAttributeNode ('action'); var nameNode = fDom. geAttributeNode ('name'); var idNode = fDom. geAttributeNode ('id'); console. log (actionNode. value );//. /add. aspxconsole. log (nameNode. value); // frmconsole. log (idNode. value); // frm copy code ②: cannot obtain the absolute path through href, src, and so on? Unlike other attributes, for href, src, and other attributes, the behavior characteristics of the dot-based mode are assimilated by getAttribute, and only static attribute values can be obtained. What should we do? IE enhances getAttribute as follows. GetAttrbute ({String} property name, {Number} [0 | 1 | 2 | 4]): Default Value 0, indicating the use of IE default behavior; 1, the property name is case sensitive; 2, obtain the static property value of an attribute. 4. Obtain the absolute path. 11. Others: standard browsers (Chrome, FF, etc.) for non-standard behaviors of the tabIndex attribute in IE are only form elements (a, area) and link elements (input, button, select, textarea, the default value of the tabIndex attribute of object is 0, while that of other elements is-1. In IE, the default value of tabIndex is 0 for all elements. 12. The summary was originally intended to fix getAttribute and other methods in view of the differences between IE5.5, 6, 7 and other browsers, the bugs of IE and the characteristics of various types of attributes, but we found that the depth of the attribute system is ah, patching for native APIS is cost-effective and not as easy as repackaging and listing like JQuery. As a result, this article only records some pitfalls of the property system, which is not comprehensive enough and has not yet been able to propose effective encapsulation methods.