JQuery3 1 1原始碼解讀 十 hooks

2021-08-10 14:54:37 字數 4813 閱讀 7855

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原始碼解讀一

前言 我為什麼要看這個原始碼,很簡單,尋找我自己寫的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...