さて、基本的に、の値はonclick
要素がクリックされたときに呼び出される関数です。ユーザーが要素をクリックしたときに何をしたいのかは、関数の本体に入ります。
名前付き関数を作成し、それを要素のonclick属性に割り当てることができます。
function youClickedMe() {
...
}
a.onclick = youClickedMe
しかし、それは他のどこでも参照されることのない関数名で名前空間を乱雑にします。必要な場所に匿名関数を作成する方がクリーンです。通常、これは次のようになります。
a.onclick = function() { ... }
しかし、あなたの特定の例でそれを試してみると:
a.onclick = function() {
ytplayer_playitem = something; // ??
ytplayer_playlazy(1000);
}
再生されるをハードコーディングしていることsomething
がわかります。元のコードは、再生するためのクリック可能なリンクをいくつか生成するループから取得されたと想定しています。上記のコードでは、これらのリンクはすべて同じように機能しますが、これはおそらくあなたが望むものではありません。
これまでのところ、とても簡単ですが、この次の飛躍はそれがトリッキーになるところです。解決策は明らかなようです。ループ内にいる場合は、関数本体内でループ変数を使用しないのはなぜですか。
// THIS DOESN'T WORK
a.onclick = function() {
ytplayer_playitem = i;
ytplayer_playlazy(1000);
}
それは機能するはずですが、残念ながら、関数の内部は、関数が作成されたときではなく、関数が呼び出されi
たときの変数の値を参照します。ユーザーがリンクをクリックするまでに、すべてのリンクを作成したループが実行され、ループの記述方法に応じて、最終的な値(おそらく、リストの最後のアイテムまたはそのアイテムのインデックスより1つ大きいアイテム)が作成されます。 。その値が何であれ、すべてのリンクが同じアイテムを再生するという状況が再び発生します。i
i
コードのソリューションは、戻り値が別の関数である関数を使用することで、少しメタを取得します。ループ制御変数を引数として母関数に渡すと、それが作成する新しい関数はそのパラメーターを参照し、次の理由で外部引数変数の値に何が起こったとしても、常に最初に渡された値を取得できます。
function generate_onclick(j) {
// no matter when the returned function is called, its "j" will be
// the value passed into this call of "generate_onclick"
return function() { ytplayer_playitem = j; ytplayer_playlazy(1000); }
}
これを使用するには、次のようにループ内で呼び出します。
a.onclick = generate_onclick(i);
生成された各関数は、独自のj
変数を取得します。この変数は、いつ変更されるかではなく、その値を永久に保持しますi
。したがって、各リンクは正しい役割を果たします。任務完了!
これは、投稿された元のコードが行っていることとまったく同じですが、1つの小さな違いがあります。私の説明の最初のステップと同様に、作成者は名前付き関数を定義する代わりに無名関数を使用することを選択しました。ここでの他の違いは、定義した直後にその匿名関数も呼び出していることです。このコード:
a.onclick = (function (j) { ... })(i)
このコードの匿名バージョンは次のとおりです。
function gen(j) { ... }
a.onclick = gen(i)
JavaScriptのセミコロン挿入規則のため、匿名バージョンの周りに追加の括弧が必要です。function (y) {...}(blah)
スタンドアロンの関数定義としてコンパイルされ、その後に関数呼び出しではなく、括弧で囲まれたスタンドアロンの式が続きます。