次のように、関数呼び出しを使用して各ハンドラーの次のコンテキストを作成することでそれを行うことができます (ただし、以下を参照)。
var ratings = new Array("happy", "clean");
for(y = 0; y < 2; y++)
{
for(x = 0; x < 5; x++)
{
fullname = ratings[y] + '_' + x;
(function(thisx, thisy) {
document.getElementById(fullname).onmouseover = function() {
star_rate(ratings[thisy], thisx, 1);
};
document.getElementById(fullname).onmouseout = function() {
star_rate(ratings[thisy], thisx, 2);
};
})(x, y);
}
}
x
これは、 andをパラメーターとして関数に渡すことで機能し、外側のループのバージョンのandy
ではなく、引数を使用してイベント ハンドラーを設定します。(上記のイベント ハンドラーの割り当てで関数名も削除しました。[関数宣言とは対照的に] 関数式で名前を使用すると、一部のブラウザーで問題が発生します。おそらくあなたが意図したものではありません. :-) )x
y
onmouseover
しかし、それは私がそれを行うことをお勧めする方法ではありません. 要素ごとに新しい関数を作成します。代わりに、要素自体に必要な情報を属性として保存し、これらすべてに共通の関数を使用するでしょう。それが HTML5 のdata-
プレフィックスの目的です (技術的には有効ではありませんが、現在でも機能しています)。このような漠然としたもの:
var ratings = new Array("happy", "clean");
var element;
for(y = 0; y < 2; y++)
{
for(x = 0; x < 5; x++)
{
fullname = ratings[y] + '_' + x;
element = document.getElementById(fullname);
element.setAttribute('data-star-x', x);
element.setAttribute('data-star-y', y);
element.onmouseover = handleMouseOver;
element.onmouseout = handleMouseOut;
}
}
function handleMouseOver() {
star_rate(this.getAttribute('data-star-y'), this.getAttribute('data-star-x'), 1);
}
function handleMouseOut() {
star_rate(this.getAttribute('data-star-y'), this.getAttribute('data-star-x'), 2);
}
要素からデータを取得しているため、イベント バブリング (マウスオーバーとマウスアウト バブルのため) を使用して、各要素ではなくコンテナー全体にイベントをフックすることもできます。(これは「イベント委任」と呼ばれることもあります。)