Использование мышеловки по определенному элементу?

Я использую библиотеку javascript Mousetrap и хочу захватить ввод на конкретном элементе.

В сценарии есть текстовое поле для имени пользователя и пароля, к которому KnockoutJS привязывается, а затем при нажатии кнопки выполняется запрос ajax для входа в систему пользователя. Теперь, поскольку нет формы и ее не реальной кнопки, ее якорь, который JQuery UI превращается в кнопку, мне было интересно, существует ли какой-то простой способ привязки мышеловки к элементу, а не на уровне документа.

Так, например, обычное связывание мышеловки будет:

Mousetrap.bind('enter', function(event) { CallSomeAjaxMethod(); });

Теперь, когда будет проверяться, что клавиша ввода будет нажата на странице (вне элемента текстового поля), а затем сделайте что-то на ее основе. Теперь проблема заключается в том, что я хочу иметь возможность ТОЛЬКО захватить это событие всякий раз, когда оно выполняется в пределах определенного элемента.

Так, например, я хотел бы сделать что-то подобное:

var element = document.getElementById("some-element");
Mousetrap.bind('enter', element, function(event) { CallSomeAjaxMethod(); });

или, возможно, более свободно:

Mousetrap.bind('enter', function(event) { CallSomeAjaxMethod(); }).on(element);

Есть ли способ сделать это? единственный способ, которым я могу это сделать (с помощью Mousetrap), в настоящее время - связать эту область документа и просто попытаться получить элемент, на который было поднято событие, если это возможно.

Я знаю, что вы можете делать такие вещи с JQuery или vanilla js, но поскольку я уже загрузил Mousetrap, я хотел бы использовать его здесь, если это возможно.

Ответ 1

Я хотел следить за этим. Начиная с версии 1.5.0 (выпущенной сегодня), теперь это возможно изначально в Mousetrap.

Для вашего конкретного примера прежде всего вам нужно сделать

var element = document.getElementById("some-element");
Mousetrap(element).bind('enter', function(event) { CallSomeAjaxMethod(); });

Вы также можете создать новый экземпляр мышеловки, чтобы связать несколько вещей.

var mousetrap = new Mousetrap(element);
mousetrap.bind('space', _handleSpace);
mousetrap.bind('enter', _handleEnter);

Лучше всего он должен быть обратно совместимым, поэтому все ваши существующие коды будут работать.

Ответ 2

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

  • Я не знаком с KnockoutJS, но браузеры построены так, чтобы клавиша enter запускала форму, поэтому самым элегантным решением, вероятно, было бы сделать ваши входы частью формы, t нужна мышеловка вообще, чтобы вызвать форму submit. Вы можете вызвать e.preventDefault() в submit submit, чтобы убедиться, что он фактически не отправляет обратно на сервер.

  • Если вы добавите класс mousetrap в текстовый ввод, это позволит ему получать быстрые клавиши. Затем вы можете проверить e.target в своем обратном вызове, чтобы узнать, исходит ли он из этого текстового поля. Это будет выглядеть примерно так:

    HTML

    <input type="text" name="email" class="mousetrap">
    

    JS

    var input = $('input[name=email]');
    Mousetrap.bind('enter', function(e) {
        if (e.target === input[0]) {
            console.log('triggered from input');
        }
    });
    
  • Вы можете перезаписать функцию Mousetrap.stopCallback, чтобы добиться этого. Это не самое подходящее решение, но должно работать.

    HTML

    <input type="text" name="email">
    

    JS

    var input = $('input[name=email]');
    var _oldStopCallback = Mousetrap.stopCallback;
    Mousetrap.stopCallback = function(e, element, combo) {
        if (combo === 'enter') {
            return element !== input[0];
        }
        return _oldStopCallback(e, element, combo);
    }
    
    Mousetrap.bind('enter', function(e) {
        console.log('triggered from input');
    });
    

Я рассматриваю разные способы поддержки различных областей/контекстов в Mousetrap, поэтому, надеюсь, в будущем будет более простой путь.