Basic understanding
Jquery.attr is the JQUERY.ATTR,JQUERY.PROP,JQUERY.CSS to provide the underlying support, jQuery a more distinctive place is the function of overloading, such as attr, there are several overloads
- $ (' #box '). attr (' title ')
- $ (' #box '). attr (' title ', ' title ')
- $ (' #box '). attr ({title: ' title ', Data-menu-toggle: ' dropdown '})
- $ (' #box '). attr (' title ', function () {...})
But throughout the jquery.attr code, but did not determine if value is not there ah kind of, OK, you guessed right, in access to achieve the
jQuery.fn.extend ({attr:function(name, value) {returnJquery.access ( This, jquery.attr, name, value, Arguments.length > 1); }, Removeattr:function(name) {return This. each (function() {jquery.removeattr ( This, name); }); }, prop:function(name, value) {returnJquery.access ( This, Jquery.prop, name, value, Arguments.length > 1); }
});
Source Code Analysis General Ideas
1. First determine whether the key value is not an object, if it is, traverse key, recursively call jquery.access, and will be chained to call the flag bit set to True
2. Determine if value is defined, If it is already defined, the description is a set operation
2.1 Set operation is 2.2 of the chained call
if value is not a function, set raw to True 2.3 to
judge Whether the key value is null or if Undefined,key is a null value
2.3.1 If value is not a function, or if the value is forced to be true, then the call to FN may be the following call: $ (' #box '). attr (null {abc: ' Def ', A: ' 1 '})
2.3.1 If value is a function, wrap FN, change the scope of the original fn and parameter
2.4 If FN exists, traverse the jquery internal meta The set operation
3. First determine whether the set method, if it is, returns Elems if it is not a get operation (if jquery internal length is 0, returns the specified default null value)
Source
//multifunctional method to get and set values of a collection //The value/s can optionally be executed if it s a function /** Attr:function (name, value) {return jquery.access (this, jquery.attr, name, value, Arguments.length > 1); }, * * @param elems jquery this * @param fn function * @param key property * @param value * @param chainable Whether the call can be chained, if it is a get action, false if it is a set action, true * @param emptyget if jquery is not selected to the return value of the element * @param raw value is the original data if Raw is Tru E, indicating that value is the original data, and if False, indicates that raw is a function * @returns {*}*/Access:function(Elems, FN, key, value, chainable, Emptyget, raw) {vari = 0, Length=elems.length, Bulk= Key = =NULL;//bulk volume, capacity, majority, bulk, bulk //sets many values /** * If the parameter key is an object indicating that you want to set multiple properties, traverse the parameter key, and traverse the call to the access method * * $ (' #box '). attr ({data:1,def: ' addd '}); */ if(Jquery.type (key) = = = "Object") {chainable=true;//indicates that a chain call can be for(Iinchkey) {jquery.access (Elems, FN, I, Key[i],true, Emptyget, Raw); } //Sets one value /** * $ (' #box '). attr (' Customvalue ', ' abc ') * $ (' #box '). attr (' Customvalue ', function (value) {}); */ } Else if(Value!==undefined) {chainable=true; if( !jquery.isfunction (value)) {Raw=true; } if(BULK) {//if (key = = null && value!== undefined) //Bulk operations run against the entire set /** * $ (' #box '). attr (Undefined, ' abc ') * * JQuery.attr.call (Elems,value); After the call is complete, set fn to empty*/ if(Raw) {Fn.call (elems, value); FN=NULL; //... except when executing function values /** * $ (' #box '). attr (Undefined,function () {}) * * fn = bulk = Jquery.attr; * * fn = function (Elem, key, value) {* Return JQuery.attr.call (JQuery (Elem), Val UE); * } * */ } Else{//If key has a value, OK, here's bulk to save a variable, save FN with bulk, and then encapsulate the call to FNBulk =fn; FN=function(Elem, key, value) {returnBulk.call (JQuery (elem), value); }; } } //jquery.access (elems,jquery.attr,) //if FN is present, the call to each element, regardless of whether the key has a value, will go to this judgment, execute the set action if(FN) {//recursive invocation of for(; i < length; i++) {fn (elems[i], key, Raw?Value:/** * If value is the original data, take value, and if it is a function, call the function value * $ (' #box '). attr (' abc ', FUNCT Ion (Index,value) {index points to the current element, value points to oldvalue * * Call Jquery.attr First (ele Ments[i],key) Take the current value and call the incoming FN value *}); */Value.call (Elems[i], I, FN (Elems[i], key)); } } } /** * If chainable is true, the description is a set method, it returns ELEMS * Otherwise the description is a Get method * 1. If bulk is true, it means that there is no key value, call FN, and transfer elems into * 2. If bulk is false, it indicates that key has a value, and then determines if the length of the element is greater than 0 * 2.1 If it is greater than 0, call FN, pass in elems[0] and key, complete get * 2.2 If 0, description There is a problem with the parameter, return the specified null value Emptyget*/ returnChainable?Elems://GetsBulk?Fn.call (elems): Length? FN (elems[0], key): Emptyget; },
The Flexsetter method in ExtJS
This makes me suddenly think of the Ext Flexsetter method, the method in Ext.Function.flexSetter detailed API see here
Usage:
var ele = document.getElementById (' box '); function SetAttribute (name, value) { Ele.setattribute (name, value); } var flexsetattribute = Ext.Function.flexSetter (setAttribute); Flexsetattribute (' title ', ' title '); Flexsetattribute ({ ' abc ': ' Otherattribu ', ' other ': 1 });
Source
/** 1. About the implementation of Ext.enumerables * * Here in order to be compatible with some browser tostring,valueof such as built-in methods cannot be traversed out of the bug * var o = {Tostring:111,va LUEOF:222}; * * for (Var oo in o) * {alert (OO); } * */ varEnumerables = [//' hasownproperty ', ' isprototypeof ', ' propertyisenumerable ',' ValueOf ', ' tolocalestring ', ' toString ', ' constructor ']; for(Iinch{tostring:1}) {Enumerables=NULL; } ext.function={flexsetter:function(setter) {return function(name, value) {//returns a closed packet vark, I; if(Name!==NULL) { if(typeofName!== ' string ') {//If name is not a string, it is assumed to be an object, for(kinchname) { if(Name.hasownproperty (k)) {Setter.call ( This, K, name[k]);//Call Setter Individually } } if(ext.enumerables) { for(i = Ext.enumerables.length; i--;) {k=Ext.enumerables[i]; if(Name.hasownproperty (k)) {Setter.call ( This, K, name[k]); } } } } Else{Setter.call ( This, name, value);//if it is a string, it is called directly } } return This; }; } };
Summary: It is clear that the flexsetter of ext is not strong, but rigorous enough, jquery.access for prop, attr and other upper layers need to be flexible set parameters of the function to do a unified collation, convenient to call, saving bit.