JSフックのメカニズムと実現
6119 ワード
JSフックのメカニズムと実現
[フックとは何か]
WordPressに触れたことのある友人なら誰でも知っているように、WPのプログラムではフックのような関数を実行することができますが、もちろんこのPHPで実現されたフックです.JAVACSCRIPTでも同様の機能が実現できる.
フックは、実行する必要がある関数または他の一連の動作を統合されたエントリに登録し、プログラムはこのフックを呼び出すことで登録された関数を実行します.
[なぜフックを使うのか]
多くの友达はwindowのような関数を書きます.onload、$(document).readyなど、1つのページに類似の関数が1つ以上書かれていますが、これらの実行する必要がある関数を統一的なエントリで実行するにはどうすればいいですか(つまり、ページはwindow.onloadのような関数を1つだけ実行する必要があります).
この場合、HOOKを使用して実装できます(window.onloadを例に挙げると)、ページのロード時に実行する関数をエントリに登録する必要があります.たとえば、次のようにします.
view source
print ?
上にはloadedフックに2つの関数が掛けられていることを示しています.次に、次のようなフックを実行します.
view source
print ?
これにより、前にどれだけの関数を掛けてもaddAction(「loaded」、function)、hooks.doAction(「loaded」)はここで統一的に実行された.
[JSフックの実装方法]
原理は比較的簡単で、hook配列を定義し、addAction時に関数pushをhook配列に、doAction時にhook配列の関数を逐一呼び出す.
view source
print ?
上はJSフック関数の定義ですが、不適切な点があれば、ご指摘ください.
[フックとは何か]
WordPressに触れたことのある友人なら誰でも知っているように、WPのプログラムではフックのような関数を実行することができますが、もちろんこのPHPで実現されたフックです.JAVACSCRIPTでも同様の機能が実現できる.
フックは、実行する必要がある関数または他の一連の動作を統合されたエントリに登録し、プログラムはこのフックを呼び出すことで登録された関数を実行します.
[なぜフックを使うのか]
多くの友达はwindowのような関数を書きます.onload、$(document).readyなど、1つのページに類似の関数が1つ以上書かれていますが、これらの実行する必要がある関数を統一的なエントリで実行するにはどうすればいいですか(つまり、ページはwindow.onloadのような関数を1つだけ実行する必要があります).
この場合、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フックに2つの関数が掛けられていることを示しています.次に、次のようなフックを実行します.
view source
print ?
1.
window.onload =
function
()
2.
{
3.
hooks.doAction(
"loaded"
);
4.
}
これにより、前にどれだけの関数を掛けても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 = (
new
Function(
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フック関数の定義ですが、不適切な点があれば、ご指摘ください.