hooks 在英語中的意思表示鉤子或掛鉤,在 jquery 中也有 hooks 這麼乙個概念,它的功能在考慮到一些相容性和其它特殊情況的條件下,優先考慮這些特殊情況,而後才去用普通的方法處理,這種說法還是比較形象的。
hooks 的使用非常用技術含量,可以支撐在原來的基礎上擴充套件,而對於介面則無需改變,舉個例子,像fn.css()
這個函式我們都是非常熟悉的了,拿來就用,而不需要考慮瀏覽器的相容性,這裡的相容性包括 border-radius 相容,使用的時候不需要在前面加上 -webkit- 瀏覽器標識。而 css 函式的內部則是借助$.csshooks()
來實現這種「鉤子」的效果的,擴充套件的時候,也是在這個物件上進行擴充套件。
不急著上來就談 hooks,先來看看 hooks 涉及到的應用。乙個典型的應用就是fn.attr
和fn.prop
,這兩個原型函式的作用是用來給 jquery 物件繫結元素的,如果不了解,可以參考這兩個鏈結,attr,prop。
雖然它們都是新增屬性,卻是不同的方式,其中,attr 是把屬性放到 html 中(實際上是 elem.attributes 屬性),而 prop 是把屬性新增到 dom 物件上,可以通過 [.] 來讀取。
那麼什麼叫做 html 中?就是我們常說的data-
資料:
var body = $('body');
body.attr('data-name','body');
// body.data('name'); //'body'
attr 方法是對應於 jquery 中的方法,而內部是通過 setattribute,getattribute 這種低階 api 來實現的,而且在 dom 物件的 attributes 屬性上是可以找到繫結值的,所以 attr 和 prop 是兩種不同的方法。
這兩個函式有四個功能,分別包括讀取和設定,如果引數只有乙個,表示讀(如果引數是 object 另外考慮),引數為兩個,表示寫。
當然,除此之外,還有 removeattr 和 removeprop 方法,原始碼如下:
jquery.fn.extend(,
removeattr: function
(name) );
},prop: function
(name, value) ,
removeprop: function
(name) );
}})
先看 attr 和 prop,都是通過access
函式,至少傳入的引數不同,乙個是 jquery.attr,乙個是 jquery.prop。來看看 access:
var access = function
( elems, fn, key, value, chainable, emptyget, raw )
// 設定乙個值
} else
if ( value !== undefined )
// key 為 null 的情況
if ( bulk ) else ;}}
// 函式執行在這裡
if ( fn )
}} if ( chainable )
// gets
if ( bulk )
// 這個返回值是比較熟悉的,即 get
return len ? fn( elems[ 0 ], key ) : emptyget;
}
access 不是今天的重點,函式不是很難,原始碼讀起來挺有意思。
來看看 jquery.attr 和 jquery.prop:
jquery.attr = function
(elem, name, value)
// 如果連這個函式都不支援,還是用 prop 方法吧
if (typeof elem.getattribute === "undefined")
// 先處理 hooks,優先考慮非正常情況
if (ntype !== 1 || !jquery.isxmldoc(elem))
// value 為 underfined 的時候呼叫 remove
if (value !== undefined)
// hooks.set
if (hooks && "set"
in hooks && (ret = hooks.set(elem, value, name)) !== undefined)
// 非 hooks 情況,正常 set
elem.setattribute(name, value + "");
return value;
} // hooks.get
if (hooks && "get"
in hooks && (ret = hooks.get(elem, name)) !== null)
// 正常 get 方法
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)
if (ntype !== 1 || !jquery.isxmldoc(elem))
if (value !== undefined)
return elem[name] = value;
} if (hooks && "get"
in hooks && (ret = hooks.get(elem, name)) !== null)
return elem[name];
}
可以看得出來,jquery.attr
和jquery.prop
方法是真的非常像,但是如果你不懂 hooks,可能會有很不疑問,這個不急。可以總結出大致的處理流程:先判斷 dom 型別,然後根據一些特殊情況,複製 hooks 引數,這裡的特殊條件為(ntype !== 1 || !jquery.isxmldoc(elem))
,接著對於 set 和 get 方法判斷,通過 value 值是否為 underfined,如果 hooks 中有,用 hooks 中提供的方法,沒有,就走正常流程。
已經知道在**使用 hooks,那麼 hooks 長什麼樣呢:
jquery.extend(
return value;}}
}},
prophooks:
}}})
// jquery 內部擴充套件
// 對於不支援 selected 的情況
if(!support.optselected),
set: function
() }
}
在 attr 的 attrhooks 中,用來處理的特殊情況是name=type
的情況,或許是這種情況,type 繫結不到 html 中。在 prop 的 prophooks 中,處理的特殊情況是 tabindex,下面還擴充套件了乙個 selected 方法,如果瀏覽器不支援 select,就建乙個 hooks。
所以乙個基本的 hooks(jquery 內部的)應該長這樣:
jquery.extend(,
set: function
(), other: function
() }
})
get 和 set 是非必需的,這是因為 attr 和 prop 的特殊性造成的,在看乙個例子jquery.fn.val
,val 的介紹 jquery.val,val 也有乙個 valhooks 與之對應:
jquery.extend(
},select: ,
set: function
() }
}})
valhooks 和之前略有不同,又多了一層,但基本思路是一致的。
jquery 內部的 hooks 功能是非常強大的,不過令人感覺欣慰的是可以在外部擴充套件。
比如有乙個問題,我們之前解釋 attr 的時候,知道它可以新增 html 的 attribute,但有一些固有的,比如class
,我們就是想在它上面新增,但又不能影響原有的 class 屬性,可以這樣來修改:
jquery.attrhooks.class = ,
get: function
(elem)
}//測試
body.attr('class','test');
// body.attr('class'); // 'test'
perfect!
hooks 講這麼多,應該就 ok 了。hooks 算是 jquery 中乙個非常可以借鑑的用法,以前聽到這個概念是非常恐懼的,當看了原始碼,弄懂原理之後,發現超級有意思。
仍然有不足,比如 jquery 中乙個非常有重量級的csshooks
就沒有提到,還是腳踏實地吧。
jquery 2.0.3 原始碼分析 鉤子機制 - 屬性操作jquery hooks
jquery.csshooks
jquery.val
jquery hooks原始碼學習
jQuery原始碼解讀一
前言 我為什麼要看這個原始碼,很簡單,尋找我自己寫的js框架與jquery之間的差異,取長補短,最終目標是提高js程式設計的乙個眼界,看看別人是怎麼想的,因為自己乙個人的想法往往是片面的,也為了能讓自己的主觀漸漸接近客觀事實。雖然jquery框架能直接拿來用,但是對於偏愛研究的人來說,還是喜歡寫原生...
jquery原始碼解讀1
function global,factory returnfactory w else pass this if window is not defined yet typeofwindow undefined window this,function window,noglobal 其中形參gl...
(十)redis原始碼解讀
redis是 單執行緒,所有命令 set,get等 都會加入到佇列中,然後乙個個執行。1 基於記憶體 2 redis協議resp 簡單 可讀 效率高 redis是乙個serversocket伺服器,而jedis是乙個socket客戶端類似redis cli,用於與redis通訊,而redis和jed...