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


92

С кодом jQuery, например:

$("#myid").click(myfunction);

function myfunction(arg1, arg2) {/* something */}

Как передать аргументы myfunctionпри использовании 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 );

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"
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.