Проблема области видимости переменной Javascript с событием jquery click - PullRequest
0 голосов
/ 23 сентября 2011

Я пытаюсь назначить серию объектов, хранящихся в массиве, обработчикам событий jquery-кликов.

Проблема в том, что при возникновении события я только ссылаюсь на последний объект в массиве.

Я собрал простой пример, чтобы показать проблему:

function dothis() {
    this.btns = new Array('#button1', '#button2');
}

// Add click handler to each button in array:
dothis.prototype.ClickEvents = function () {

    //get each item in array:
    for (var i in this.btns) {

        var btn = this.btns[i];
        console.debug('Adding click handler to button: ' + btn);

        $(btn).click(function () {
            alert('You clicked : ' + btn);
            return false;
        });
    }
}

var doit = new dothis();
doit.ClickEvents();

Форма HTML содержит пару кнопок:

<input type="submit" name="button1" value="Button1" id="button1" />
<input type="submit" name="button2" value="Button2" id="button2" />

Когда нажимается кнопка 1, она говорит«Вы нажали # Button2»

Похоже, что оба обработчика нажатия кнопок указывают на один и тот же объект внутри var btn.

Учитывая, что переменная находится внутри цикла for, я не могу понять, почему.

Есть идеи?

Ответы [ 5 ]

4 голосов
/ 23 сентября 2011

Вам нужна фабрика функций, чтобы закрыть переменную цикла, например:

//get each item in array:
for (var i=0; i<this.btns.length; i++) {

    $(this.btns[i]).click(function(item) { 
        return function () {
            alert('You clicked : ' + item);
            return false;
        }
    }(this.btns[i]));

}

Еще один хороший вариант - позволить jquery помочь вам. Используйте jQuery.each (). Переменная btn здесь локальна для функции-обработчика и поэтому не используется повторно между итерациями. Это позволяет вам закрыть его и сохранить его значение.

$.each(this.btns, function() {
    var btn = this;
    $(this).click(function () {
        alert('You clicked : ' + btn);
        return false;
    }
});
2 голосов
/ 28 октября 2011

в обработчике события 'this' обычно относится к элементу, инициирующему событие, в данном случае это будет ваша кнопка

поэтому решение вашей проблемы довольно простое, вместо ссылки на переменную btn, которая находится в более широкой области видимости и мутирует задолго до запуска обработчика события, мы просто ссылаемся на элемент, вызвавший событие, и получаем его идентификатор

$(btn).click(function () {
  alert('You clicked : #' + this.id);
  return false;
});

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

К счастью, обработчик щелчка (и все другие обработчики событий afaik) принимает дополнительный параметр для eventData, полезный примерно так:

$(btn).click(btn, function (event) {
  alert('You clicked : #' + event.data);
  return false;
});

Используйте массив, если вы передаете несколько вещей:

$(btn).click(['foo', 'bar'], function (event) {
  alert('this should be "foo": ' + event.data[0]);
  alert('this should be "bar": ' + event.data[1]);
  return false;
});
0 голосов
/ 23 сентября 2011

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

$(btn).click(function () {
    return function() {
        alert('You clicked : ' + btn);
        return false;
    }
});
0 голосов
/ 23 сентября 2011

возможно вам нужно изменить только привязку клика:

$(btn).click(function () {
    alert('You clicked : ' + $(this).attr('id'));
    return false;
});
0 голосов
/ 23 сентября 2011

Ваша проблема здесь:

alert('You clicked : ' + btn);

btn сохраняет значение с момента последнего вызова в цикле.Считайте значение с кнопки в событии.

    $(btn).data('selector', btn).click(function () {
        alert('You clicked : ' + $(this).data('selector'));
        return false;
    });

http://jsfiddle.net/Mc9Jr/1/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...