// JS钩子示例 // JS对于不同消息类型,实现了不同的调用链 // 事件触发的时候,根据消息类型,调用对应的调用链 // 同一个钩子函数,安装多次,会根据安装顺序,调用多次 // 可以对比Windows API的钩子如SetWindowsHookEx等,原理上很相似 // 储存全部事件的调用链函数列表 function hooks() { this.queue = new Array(); } // 通过addAction,生成调用链 hooks.prototype.addAction = function (hook, func) { // 某一个事件的调用链函数列表 if(this.queue[hook]==undefined){ this.queue[hook] = new Array(); } if (typeof func == 'function') { this.queue[hook].push(func); } else if (typeof func == 'string') { this.queue[hook].push(this.window[func]); } } // 通过doAction,实现调用链 hooks.prototype.doAction = function (hook) { var parameters = Array.prototype.slice.call(arguments, 1); var functions = this.queue[hook]; for (var i = 0; i < functions.length; i++) { this.call_user_func_array(functions[i], parameters); } return true; } // 实现具体钩子函数调用 hooks.prototype.call_user_func_array = function(cb, parameters) { if (typeof cb === 'string') { func = (typeof this[cb] === 'function') ? this[cb] : func = (newFunction(null, 'return ' + cb))(); } else if (cb instanceof Array) { func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]]; } else if (typeof cb === 'function') { func = cb; } if (typeof func != 'function') { throw new Error(func + ' is not a valid function'); } if (typeof parameters == 'undefined') { var tmp_ary = []; var parameters = Array.prototype.slice.call(tmp_ary, 1); } return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters); } function func1() { console.log("func1"); } function func2() { console.log("func2"); } function func3() { console.log("func3"); } // 使用示例 var myhook = new hooks(); myhook.addAction("loaded", func3); myhook.addAction("loaded", func2); myhook.addAction("loaded", func1); myhook.addAction("loaded", func3); myhook.doAction("loaded")