jQuery 原始碼系列(十)hooks 的原理

2021-09-17 02:49:47 字數 4826 閱讀 1711

歡迎來我的專欄檢視系列文章。

hooks 在英語中的意思表示鉤子或掛鉤,在 jquery 中也有 hooks 這麼乙個概念,它的功能在考慮到一些相容性和其它特殊情況的條件下,優先考慮這些特殊情況,而後才去用普通的方法處理,這種說法還是比較形象的。

hooks 的使用非常用技術含量,可以支撐在原來的基礎上擴充套件,而對於介面則無需改變,舉個例子,像fn.css()這個函式我們都是非常熟悉的了,拿來就用,而不需要考慮瀏覽器的相容性,這裡的相容性包括 border-radius 相容,使用的時候不需要在前面加上 -webkit- 瀏覽器標識。而 css 函式的內部則是借助$.csshooks()來實現這種「鉤子」的效果的,擴充套件的時候,也是在這個物件上進行擴充套件。

不急著上來就談 hooks,先來看看 hooks 涉及到的應用。乙個典型的應用就是fn.attrfn.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.attrjquery.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原始碼分析系列

斷斷續續地看jquery原始碼,第一次萌生看jq原始碼的念頭,當時還是版本1.7.2,由於工作中沒有用到jq的機會,連 有幾種用法都還不知道,就開始啃原始碼,痛苦自然是少不了的,於是不久就放棄扔一邊了。等到工作中終於就機會用jq了 撒花 又萌生了啃jq原始碼的念頭,此時jq版本已經是2.0了。鑑於瀏...

jQuery原始碼分析系列

版本截止到2013.8.24 jquery官方發布最新的的2.0.3為準 附上每一章的原始碼注釋分析 正在編寫的書 jquery架構設計與實現 本人在慕課網的教程 完結 jquery原始碼解析 架構與依賴模組 64課時 jquery原始碼解析 dom與核心模組 64課時 jquery原始碼分析目錄 ...

jQuery原始碼分析系列 Callback深入

關於callbacks callbacks 的內部提供了jquery的 ajax 和 deferred 基本功能元件 在針對ajax處理中,用的最多的就是once memory的組合 所有的 佇列,不管任何時候增加的 保證只觸發一次 type completedeferred jquery.call...