JS钩子的机制与实现

来源:互联网 发布:淘宝金钻买家 编辑:程序博客网 时间:2024/06/06 16:36

JS钩子的机制与实现

[什么是钩子]

        接触过WordPress的朋友都知道,WP的程序中可以执行类似钩子的函数,当然是这PHP实现的钩子。在JAVASCRIPT中一样可以实现类似的功能。

       用一句话来形容一下:钩子是将需要执行的函数或者其他一系列动作注册到一个统一的入口,程序通过调用这个钩子来执行这些已经注册的函数。

[为什么要用钩子]

很多朋友都会写一些函数,类似window.onload、$(document).ready等,而且一个页面不止一处写到类似的函数,如何让这些需要执行的函数在一个统一的入口执行(即页面只需要执行一个类似window.onload的函数)?

这时我们可以借助HOOK来实现,(以window.onload为例)将所以需要在页面加载的时候执行函数都注册到一个入口,如:

view source
print?
01.function func1()
02.{
03.// ....
04.}
05.function func2()
06.{
07.// ....
08.}
09.hooks.addAction("loaded", func1);    // 添加函数
10.hooks.addAction("loaded""func2");

上面表示在loaded钩子上挂了两个函数。然后执行这个钩子,如:

view source
print?
1.window.onload = function()
2.{
3.hooks.doAction("loaded");
4.}

这样无论在之前挂多少函数hooks.addAction("loaded", function),在hooks.doAction("loaded")这里都被统一执行了。

[JS钩子如何实现]

原理比较简单,定义一个hook数组,addAction时将函数push到hook数组,doAction时将hook数组里的函数逐一调用。

view source
print?
01.function hooks()
02.{
03.this.queue = new Array();
04.}
05. 
06.hooks.prototype.addAction = function(hook, func)
07.{
08.this.queue[hook] = new Array();
09.if(typeof func == 'function') {
10.this.queue[hook].push(func);
11.else if(typeof func == 'string') {
12.this.queue[hook].push(this.window[func]);
13.}
14.}
15. 
16.hooks.prototype.doAction = function(hook)
17.{
18.var parameters = Array.prototype.slice.call(arguments, 1);
19.var functions = this.queue[hook];
20.for(var i=0; i < functions.length; i++)
21.{
22.this.call_user_func_array(functions[i], parameters);
23.}
24.return true;
25.}
26. 
27.hooks.prototype.call_user_func_array = function(cb, parameters)
28.{
29.if (typeof cb === 'string') {
30.func = (typeof this[cb] === 'function') ? this[cb] : func = (newFunction(null'return ' + cb))();
31.else if (cb instanceof Array) {
32.func = ( typeof cb[0] == 'string' ) ? eval(cb[0]+"['"+cb[1]+"']") : func = cb[0][cb[1]];
33.else if (typeof cb === 'function') {
34.func = cb;
35.}
36.if (typeof func != 'function') {
37.throw new Error(func + ' is not a valid function');
38.}
39.if(typeof parameters == 'undefined') {
40.var tmp_ary = [];
41.var parameters = Array.prototype.slice.call(tmp_ary, 1); 
42.}
43.return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) :
44.typeof cb[0] !== 'object' ) ? func.apply(null, parameters) : func.apply(cb[0], parameters);
45.}

上面是JS钩子函数的定义,如有不妥之处,欢迎指正。