Как использовать функцию как обработчик события и быть вызванным напрямую с параметрами?

56
7

В сценарии jQuery у меня есть функция, которая обычно вызывается в ответ на клик, поэтому действует как обработчик событий, но мне также нужно вызвать ее напрямую. В обоих случаях ему нужны некоторые параметры.

Таким образом, упрощенная ситуация такова:

function go(e) {
console.log(e.data.dir)
}

$("body").keydown(function(e) {
if (e.which == 37) { // left
go({dir: 'forward'});
} else if (e.which == 39) { // right
go({dir: 'forward'});
}
});

$('.forward').on('click', {
dir: 'forward'
}, go);

Здесь скрипка

Это явно не работает, потому что, когда я вызываю функцию напрямую, нет ключа data. Обходным решением было бы вызвать такую функцию:

go({data: {dir: 'forward'}});

И это работает, но довольно уродливо. Каким будет правильный подход в таком случае?

спросил(а) 2016-03-31T22:11:00+03:00 4 года, 3 месяца назад
1
Решение
54

Есть два способа, которыми я могу это понять.

    Вы можете сохранить объект параметра в переменной вверху вашего скрипта и передать переменную go() когда вам нужно вызвать ее за пределами обработчика кликов. Это сделало бы вещи немного менее уродливыми. Или вы можете проверить, является ли e null в go(), и если это так, используйте/установите некоторые общие значения по умолчанию.

Либо было бы приемлемо, в зависимости от того, что должен делать весь метод.

ответил(а) 2016-03-31T22:19:00+03:00 4 года, 3 месяца назад
55

В этом конкретном случае вы можете решить проблему с помощью apply() и просто передать аргументы из обработчика событий, если условие является правдивым

function go(e) {
console.log(e.data.dir)
}

$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39) {
go.apply(this, arguments);
}
});

$('.forward').on('click', {dir: 'forward'}, go);

FIDDLE

Или вы можете передать объект с соответствующими свойствами

$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39)
go({data:{dir: 'forward'}});
});

или вызвать событие click с помощью специального события

$("body").on('keydown', {dir: 'forward'}, function(e) {
if (e.which === 37 || e.which === 39)
$('.forward').trigger('click', [{data: {dir: 'forward'}}] );
});

ответил(а) 2016-03-31T22:30:00+03:00 4 года, 3 месяца назад
56

Я думаю, что я сделал бы что-то вроде этого (если мне не понадобится событие):

function go(data) {
console.log(data.dir)
}

$("body").keydown(function(e) {
if (e.which == 37) { // left
go({dir: 'forward'});
} else if (e.which == 39) { // right
go({dir: 'forward'});
}
});

$('.forward').on('click', function(){
go({dir: 'forward'});
});

ответил(а) 2016-03-31T22:20:00+03:00 4 года, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема