Подтвердить что ты не робот

Как передать параметр в функцию, используя в addEventListener?

Традиционным способом добавления прослушивателя событий:

function getComboA(sel) {
    var value = sel.options[sel.selectedIndex].value;  
}

<select id="comboA" onchange="getComboA(this)">
<option value="">Select combo</option>
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
<option value="Value3">Text3</option>
</select>

Но я хотел адаптироваться к способу addEventListener:

productLineSelect.addEventListener('change',getSelection(this),false);

function getSelection(sel){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
}

Это не работает, потому что я не могу передать какой-либо параметр в getSelection() в качестве второго параметра в методе addEventListener? Насколько я знаю, я могу использовать имя функции без заключений в скобках.

Любая идея?

Кстати, посмотрите мой предыдущий вопрос о том, что console.log не работает в инспекторе разработчиков Safari 6.0, я не могу писать какой-либо вывод в консоли, что расстраивает.

4b9b3361

Ответ 1

Не нужно ничего пропускать. Функция, используемая для addEventListener, автоматически привяжет this к текущему элементу. Просто используйте this в своей функции:

productLineSelect.addEventListener('change', getSelection, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}

Здесь скрипка: http://jsfiddle.net/dJ4Wm/


Если вы хотите передать произвольные данные функции, оберните ее в свой анонимный вызов функции:

productLineSelect.addEventListener('change', function() {
    foo('bar');
}, false);

function foo(message) {
    alert(message);
}

Здесь скрипка: http://jsfiddle.net/t4Gun/


Если вы хотите вручную установить значение this, вы можете использовать метод call для вызова функции:

var self = this;
productLineSelect.addEventListener('change', function() {
    getSelection.call(self);
    // This'll set the `this` value inside of `getSelection` to `self`
}, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}

Ответ 2

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

productLineSelect.addEventListener('change',getSelection,false);

function getSelection(){
    var value = sel.options[this.selectedIndex].value;
    alert(value);
}

Если вы хотите передать другой аргумент из контекста, где вы вызываете addEventListener, вы можете использовать закрытие, например:

productLineSelect.addEventListener('change', function(){ 
    // pass in `this` (the element), and someOtherVar
    getSelection(this, someOtherVar); 
},false);

function getSelection(sel, someOtherVar){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
    alert(someOtherVar);
}

Ответ 3

Если требуемое значение this - это просто объект, с которым вы связали обработчик событий, тогда addEventListener() уже делает это для вас. Когда вы это сделаете:

productLineSelect.addEventListener('change', getSelection, false);

функция getSelection уже будет вызываться с this, установленной для объекта, к которому привязан обработчик событий. Он также будет передан аргумент, который представляет объект события, который имеет все виды информации об объекте о событии.

function getSelection(event) {
    // this will be set to the object that the event handler was bound to
    // event is all the detailed information about the event
}

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

var self = this;
productLineSelect.addEventListener('change',function() {
    getSelection(self)
},false);

В качестве объяснения:

  • Вы сохраняете значение this в локальной переменной в вашем другом обработчике событий.
  • Затем вы создаете анонимную функцию для передачи addEventListener.
  • В этой анонимной функции вы вызываете свою фактическую функцию и передаете ей сохраненное значение this.

Ответ 4

Для начала, в первой строке вашего JS-кода:

productLineSelect.addEventListener('change', getSelection(this), false);

... вы вызываете getSelection, поместив (this) за ссылку на функцию. Это скорее всего не то, что вы хотите, потому что теперь вы передаете возвращаемое значение этого вызова addEventListener вместо ссылки на фактическую функцию.

В функции, вызываемой addEventListener, значение для this будет автоматически установлено на объект, к которому подключен слушатель, productLineSelect.

Если это то, что вы хотите, вы можете просто сделать:

productLineSelect.addEventListener('change', getSelection, false);

Если это НЕ то, что вы хотите, вам лучше bind ваше значение для этой функции, которую вы передаете в addEventListener:

var myPreferredThis = {};
productLineSelect.addEventListener('change', getSelection.bind(myPreferredThis), false);

Часть .bind также является вызовом, но этот вызов просто возвращает ту же функцию, с которой мы вызываем bind on, со значением для this внутри этой области возможностей фиксированной до аргумент, который мы передаем, таким образом, фактически переопределяя динамический характер этой привязки. Поэтому нет необходимости закрывать var self = this;.

Чтобы перейти к вашему актуальному вопросу: как передать параметры функции addEventListener:

Вам нужно будет использовать дополнительное определение функции:

var otherVar = 'accessedThroughClosure';

productLineSelect.addEventListener('change', function (eventObject) {
    var localVar = 'initializedInEventHandler';
    getSelection(eventObject, this, otherVar, localVar);
}, false);

Теперь мы передаем объект события, ссылку на значение this внутри обратного вызова addEventListener, переменную, определенную и инициализированную внутри этого обратного вызова, и переменную извне всего вызова addEventListener к вашей собственной функции getSelection.

Конечно, вы могли бы снова bind объект по вашему выбору быть this внутри вашего внешнего обратного вызова:

var myPreferredThis = {};
var otherVar        = 'accessedThroughClosure';

productLineSelect.addEventListener('change', function (eventObject) {
    var localVar = 'initializedInEventHandler';
    getSelection(eventObject, this, otherVar, localVar);
}.bind(myPreferredThis), false);