Использование одной и той же функции onmouseover для нескольких объектов - PullRequest
0 голосов
/ 15 мая 2010

Я создаю строительную игру на JavaScript и PHP, которая использует сетку. Каждый квадрат в сетке является элементом div с собственной функцией onmouseover и onmousedown:

for(x=0; x < width; x++)
{
    for(y=0; y < height; y++)
    {
        var div = document.createElement("div");
        //...
        div.onmouseclick = function() {blockClick(x, y)}
        div.onmouseover = function() {blockMouseover(x, y)}
        game.appendChild(div);
    }
}

Но у всех квадратов, похоже, есть x и y последнего квадрата, который был добавлен. Я могу понять, почему это происходит - он делает указатель на x и y вместо клонирования переменных - но как я могу это исправить? Я даже попробовал

for(x=0; x < width; x++)
{
    for(y=0; y < height; y++)
    {
        var div = document.createElement("div");
        var myX = x;
        var myY = y;
        div.onmouseclick = function() {blockClick(myX, myY)}
        div.onmouseover = function() {blockMouseover(myX, myY)}
        game.appendChild(div);
    }
}

с тем же результатом.

Я использовал div.setAttribute("onmouseover", ...), который работал в Firefox, но не в IE. Спасибо!

Ответы [ 2 ]

1 голос
/ 15 мая 2010

Вам необходимо создать замыкание, чтобы сохранить значения x и y. Это должно сделать трюк:

for(var x=0; x < width; x++) {
  for(var y=0; y < height; y++) {
    var div = document.createElement("div");
    (function(x,y){
       div.onmouseclick = function() {blockClick(x, y)}
       div.onmouseover = function() {blockMouseover(x, y)}
    })(x,y);
    game.appendChild(div);
  }
}

Более чистый способ сделать это - определить функцию для создания div и затем вызывать ее на каждой итерации:

var createDiv = function(x,y){
  var div = document.createElement("div");
  div.onmouseclick = function() {blockClick(x, y)};
  div.onmouseover = function() {blockMouseover(x, y)};
  return div;
}

for(var x=0; x < width; x++) {
  for(var y=0; y < height; y++) {
    game.appendChild(createDiv(x,y));
  }
}
0 голосов
/ 15 мая 2010

Это потому, что вы фактически используете одни и те же переменные для каждого обработчика из-за окружающего замыкания. Таким образом, вам нужно создать локальные замыкания, как это:

(function(x,y){
    div.onmouseclick = function() {blockClick(x, y)};
    div.onmouseover = function() {blockMouseover(x, y)};
})(x, y);
...