Hooks in English means hook or hook, in jQuery also has hooks such a concept, its function in consideration of some compatibility and other special circumstances, the priority to consider these special circumstances, and then to use the ordinary method of processing, this statement is still relatively image.
The use of hooks is very technical content, can be supported on the original basis of expansion, and for the interface does not need to change, for example, like fn.css () This function we are very familiar with, to use, and do not need to consider browser compatibility, where compatibility includes Border-radius Compatible, it does not need to be preceded by the-webkit-browser logo. The inside of the CSS function is the use of $.csshooks () to achieve the effect of this "hook", the extension of the time, but also on this object to expand. first of all, attr and prop.
Do not rush up to talk about hooks, first look at the application of hooks involved. A typical application is fn.attr and Fn.prop, these two prototype functions are used to give JQuery object binding elements, if you do not understand, you can refer to the two links, Attr,prop.
While they are all adding properties, they are different ways, where attr is putting attributes into HTML (which is actually the Elem.attributes property), and prop is adding properties to the DOM object that can be read by [.].
So what is called HTML. That's what we always say. data-data:
var BODY = $ (' body ');
Body.attr (' data-name ', ' body ');
<body data-name= "Body" ></body>
body.data (' name ');//' body '
The attr method corresponds to the method in JQuery, and the interior is implemented by setattribute,getattribute this low-level API, and the binding value can be found on the Attributes property of the DOM object, so attr and prop are two different methods.
The two functions have four functions, including reading and setting, if the parameter is only one, the expression reads (if the argument is an Object separately), the parameter is two, the expression is written.
Of course, in addition, there are removeattr and Removeprop methods, the source code is as follows:
JQuery.fn.extend ({
attr:function (name, value) {
return access (this, jquery.attr, name, value, Arguments.length > 1);
},
removeattr:function (name) {
return This.each (function () {
Jquery.removeattr (this, name);
}
,
prop:function (name, value) {
return access (this, Jquery.prop, Name, value, Arguments.length > 1);
},
removeprop:function (name) {
return This.each (function () { C13/>delete This[jquery.propfix[name] | | name];
});
}
)
access Method
First look at attr and prop, all through the access function, at least the parameters passed in different, one is jquery.attr, one is Jquery.prop. Take a look at access:
var access = function (Elems, FN, key, value, chainable, Emptyget, raw) {var i = 0, Len = elems.length, bulk =
key = = NULL;
parameter is an object, set multiple values at once if (Jquery.type (key) = = = "Object") {chainable = true;
For (i in key) {Access (Elems, FN, I, key[i], true, Emptyget, raw);
}//Set a value} else if (value!== undefined) {chainable = true;
if (!jquery.isfunction (value)) {raw = true;
}//key is NULL if (bulk) {if (raw) {Fn.call (elems, value);
fn = null;
Value is function} else {bulk = fn;
fn = function (Elem, key, value) {return Bulk.call (JQuery (elem), value);
};
}}//function is executed here if (FN) {for (; i < Len; i++) {fn (elems[i], key, raw?
Value:value.call (elems[i], I, FN (elems[i], key)); }}} if (chainable) {//write case returnValue return elems;
}//Gets if (bulk) {return fn.call (elems); }//This return value is more familiar, that is, get return len?
FN (elems[0], key): Emptyget; }
Access is not the focus of today, the function is not very difficult, the source read very interesting. attr and prop source code
Take a look at jquery.attr and Jquery.prop:
jquery.attr = function (elem, name, value) {var ret, hooks, nType = Elem.nodetype;
For text, comment and attribute nodes do not process if (nType = = = 3 | | nType = = 8 | | nType = = 2) {return; }//If this function is not supported, use the Prop method if (typeof Elem.getattribute = = = = "undefined") {return Jquery.prop (elem, name, Valu
e); }//Process hooks First, priority is given to abnormal if (nType!== 1 | |!jquery.isxmldoc (elem)) {hooks = Jquery.attrhooks[name.tolowercase () ] ||
(JQuery.expr.match.bool.test (name)? boolhook:undefined); }//value is underfined when you call remove if (value!== undefined) {if (value = = = null) {jquery.removeattr (elem
, name);
Return }//Hooks.set if (hooks && "set" in hooks && (ret = Hooks.set (elem, value, name))!== undefined)
{return ret;
}//non-hooks case, normal set Elem.setattribute (name, Value + "");
return value; }//Hooks.get if (hooks && "get" in hooks && (ret = Hooks.get (elem, name))!== NULL) {return ret;
}//Normal get method ret = jQuery.find.attr (elem, name); Non-existent attributes return NULL, we normalize to undefined return ret = = null?
Undefined:ret; }
jquery.prop = function (elem, name, value) {var ret, hooks, nType = Elem.nodetype; Don ' t get/set properties on text, comment and attribute nodes if (nType = = 3 | | nType = = 8 | | nType = = 2) {RE
Turn } if (NType!== 1 | |!jquery.isxmldoc (elem)) {//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;
} return Elem[name] = value;
} if (hooks && "get" in hooks && (ret = Hooks.get (elem, name))!== null) {return ret;
} return Elem[name]; }
Can be seen, jquery.attr and Jquery.prop method is really very similar, but if you do not understand hooks, there may be no doubt, this is not urgent. Can summarize the approximate processing flow: First judge the DOM type, and then according to some special cases, copy the hooks parameter, here the special condition is (nType!== 1 | |!jquery.isxmldoc (ELEM)), and then for the set and get method to judge, through the Val UE value is underfined, if hooks, with the method provided in hooks, no, go normal process. first knowledge of hooks
Already know where to use hooks, then what does hooks look like:
Jquery.extend ({
attrhooks: {
//Attrhooks compatible type of low-version browser case
type: {
set:function (Elem, value) {
I F (!support.radiovalue && value = = = "Radio" &&
jquery.nodename (elem, "input")) {
var val = ele M.value;
Elem.setattribute ("type", value);
if (val) {
elem.value = val;
}
return value;}}}
,
prophooks: {
tabIndex: {
get:function (elem) {
...
}
}
}
})
JQuery internal extension
//For cases where selected is not supported
if (!support.optselected) {
jQuery.propHooks.selected = {
get: function () {
...
},
set:function () {}}
}
In Attr's attrhooks, the special case that is used to handle is the case of Name=type, perhaps the case where the type is not bound to HTML. In prop's prophooks, the special case for handling is TabIndex, and a selected method is extended, and a hooks is built if the browser does not support select.
So a basic Hooks (JQuery inside) should look like this:
Jquery.extend ({
namehooks: {
get:function () {
...
},
set:function () {
...
},
Other:function () {
...}}
)
Get and set are non-essential because of the particularity of attr and prop, and in the introduction of an example Jquery.fn.val,val jquery.val,val there is also a valhooks corresponding to it:
Jquery.extend ({
valhooks: {
option: {
get:function () {...}
},
select: {
get:function () {...},
set:function () {...}}}
)
Valhooks and the previous slightly different, but also a layer, but the basic idea is consistent. External Extension Hooks
The hooks function within JQuery is very powerful, but it is comforting to be able to expand externally.
For example, when we explained attr before, we know that it can add HTML attribute, but there are some intrinsic, such as class, we just want to add on it, but can not affect the original class property, it is possible to modify:
JQuery.attrHooks.class = {
//The order of the parameters here two is the opposite of
set:function (Elem, value) {
return $ (elem). attr (' class-sp ') , value)
,
get:function (elem) {
return $ (elem). attr (' class-sp ');}
}
Test
body.attr (' class ', ' test ');
<body class= "Body" class-sp= "test" ></body>
body.attr (' class ');//' Test '
Perfect Summary
Hooks talk so much, should be OK. Hooks is a very useful use in jQuery, before hearing this concept is very scary, when read the source code, understand the principle, found super interesting.
There are still shortcomings, such as a very heavyweight csshooks in JQuery, not mentioned, or down to earth. Reference
JQuery 2.0.3 Source Analysis hook mechanism-property operations
JQuery Hooks
Jquery.csshooks
Jquery.val
JQuery Hooks Source Learning