Как передать аргументы обработчикам событий в jQuery?

Ответы:

111

Самый простой способ - сделать это так (при условии, что вы не хотите, чтобы какая-либо информация о событии передавалась в функцию) ...

$("#myid").click(function() {
    myfunction(arg1, arg2);
});

jsFiddle .

Это создает анонимную функцию, которая вызывается при clickзапуске события. Это, в свою очередь, вызовет myfunction()предоставленные вами аргументы.

Если вы хотите сохранить ThisBinding(значение, thisкогда функция вызывается, установить для элемента, который вызвал событие), тогда вызовите функцию с помощью call().

$("#myid").click(function() {
    myfunction.call(this, arg1, arg2);
});

jsFiddle .

Вы не можете передать ссылку напрямую, как указано в вашем примере, иначе ее единственным аргументом будет объект jQueryevent .

Если вы действительно хотите передать ссылку, вы должны использовать JQuery в proxy()функцию (которая является кросс - браузер обертка для Function.prototype.bind()). Это позволяет передавать аргументы, которые связаны , прежде чем в eventаргументе.

$("#myid").click($.proxy(myfunction, null, arg1, arg2));   

jsFiddle .

В этом примере, myfunction()будет выполнено с его ThisBindingнетронутым ( nullне является объект, поэтому нормальное thisзначение элемента , который срабатывает, используется событие), наряду с аргументами (по порядку) arg1, arg2и , наконец, JQuery eventобъекта, который можно игнорировать если он не требуется (даже не называйте его в аргументах функции).

Вы также можете использовать eventобъект jQuery dataдля передачи данных, но это потребует изменения myfunction()для доступа к нему через event.data.arg1(которые не являются аргументами функции, как упоминается в вашем вопросе) или, по крайней мере, введение ручной прокси-функции, такой как предыдущий пример или сгенерированный используя последний пример.

Алекс
источник
2
имейте в виду, что вы потеряете контекст jquery $ (this) в myfunction (). Для обслуживания вызовите myfunction(this, arg1, arg2)анонимный обработчик. Тогда ваша функция может работатьmyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator
11
@geosteve: Если вы хотите сохранить его, используйте myfunction.call(this, arg1, arg2).
Alex
1
Это не передача аргументов функции, как задается вопросом. Он вызывает функцию, которая вызывает другую функцию. Вложение функций внутри анонимных функций - не лучшая идея, поскольку вы не можете легко отвязать анонимную функцию.
Джордж Филиппакос
1
@ geo1701 Можно, если вы используете собственное пространство имен и выполняете привязку к нему только один раз. В большинстве случаев это нормально. Но вы теряете то преимущество, о котором упомянули.
Alex
1
Согласившись с @ geo1701, мне пришлось удалить обработчик событий, и его решение - только одно, которое сработало.
Pavel K
77
$("#myid").on('click', {arg1: 'hello', arg2: 'bye'}, myfunction);

function myfunction(e) {

    var arg1 = e.data.arg1;
    var arg2 = e.data.arg2;

    alert(arg1);
    alert(arg2);

}

//call method directly:
myfunction({
    arg1: 'hello agian', 
    arg2: 'bye again'
});

Также позволяет связывать и отменять привязку определенных обработчиков событий с помощью методов включения и выключения.

Пример:

$("#myid").off('click', myfunction);

Это отвяжет обработчик myfunction от #myid

Джордж Филиппакос
источник
Это не передача аргументов функции, как задается вопросом.
Alex
4
Вот как вы передаете аргументы (вы обертываете их внутри объекта).
Джордж Филиппакос
Это то, как вы передаете данные, но вызывает их аргументы функции.
Alex
7
Это лучшее решение для принятого ответа, поскольку в нем используется рекомендуемый шаблон привязки и отмены привязки слушателей с использованием методов включения / выключения.
Джордж Филиппакос,
7
Если вы думаете, что развязывание встречается довольно редко, значит, у вас очень ограниченный опыт. Пожалуйста, не путайте вклад с другими - это коллективная база знаний, а не соревнование. Там нет правильных или неправильных ответов.
Джордж Филиппакос
12

хотя вам, безусловно, следует использовать ответ Алекса, метод "привязки" библиотеки прототипов стандартизирован в Ecmascript 5 и скоро будет встроен в браузеры. Это работает так:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));
Бретонский
источник
2
Будет thisли установлен другой контекст, если вы используете этот метод, например, bind()его использование thisв этом контексте (глобальном) может привести к тому, что этот обработчик кликов будет иметь windowобъект, thisа не ссылку на #myidэлемент?
Alex
2
@alex вы совершенно правы. jQuery привяжет элемент #myid к this в своих обработчиках событий, а использование метода bind переопределит это. Я написал этот пост несколько лет назад, кажется, трудно сказать, о чем я думал в то время. Думаю, я просто предполагаю, что люди, читающие мои ответы, достаточно умны, чтобы сами выяснить эти детали.
Бретон
12
Это очень опасное предположение.
Travis
@Travis На момент написания этой статьи (почти через 11 лет после ответа Бретона) caniuse.com сообщает, что Ecmascript 5 поддерживается 98,87% браузеров. (см. caniuse.com/#search=ECMAScript%205 )
Стефан
1
@Stephan Мой ироничный комментарий был нацелен на предположение @Breton people reading my answers are smart enough to figure these details out themselves, а не на Ecmascript.
Трэвис
6

Старая ветка, но для целей поиска; пытаться:

$(selector).on('mouseover',...);

... и проверьте параметр "данные": http://api.jquery.com/on/

например:

function greet( event ) {
  alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {name: "Karl"}, greet );
$( "button" ).on( "click", {name: "Addy"}, greet );
dhc
источник
4

Уже есть отличные ответы, но в любом случае вот мои два цента. Вы также можете использовать:

$("#myid").click({arg1: "foo", arg2: "bar"}, myfunction)

И слушатель выглядел бы так:

function myfunction(event){ alert(event.data.arg1); alert(event.data.arg2); }

Лео
источник
2

Просто:

$(element).on("click", ["Jesikka"],  myHandler);

function myHandler(event){
   alert(event.data);     //passed in "event.data"
}
Т. Тодуа
источник