Domanda

I am using the Mousetrap javascript library and am wanting to capture input on a specific element.

The scenario is I have a textbox for username and password which KnockoutJS binds to then when a button is pressed an ajax request is made to login the user. Now as there is no form and its not a real button its an anchor that Jquery UI turns into a button I was wondering if there was some simple way to get mousetrap to bind to the element rather than at the document level.

So for example a normal mousetrap binding would be:

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

Now that will check for any enter key press on the page (outside of a textbox element) and then do something based on it. Now the problem is in this case I am wanting to be able to ONLY capture this event whenever it is carried out within the scope of a specific element.

So for example I would be wanting to do something likethis:

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

or maybe more fluent like:

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

Is there any way to do this? the only way I can see to do it (with Mousetrap) currently is to have this document scope binding and just try to get the element the event was raised on if it is possible.

I know you can do this sort of thing with Jquery or vanilla js however as I already have Mousetrap loaded I would like to re-use it here if possible.

È stato utile?

Soluzione

I wanted to follow up on this. As of version 1.5.0 (released today), this is now possible natively in Mousetrap.

For your specific example above all you have to do is

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

You can also create a new instance of mousetrap to bind multiple things.

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

Best of all it should be backwards compatible so all your existing code will still work.

Altri suggerimenti

As of right now the short answer to your question is there is no way to do this natively in Mousetrap. That being said there are a few ways you could approach this.

  1. I am not familiar with KnockoutJS, but browsers are built to let the enter key trigger a form submit so the most elegant solution would probably be to make your inputs part of a form in which case you don't need mousetrap at all to trigger the form submit. You could call e.preventDefault() on form submit to make sure it doesn't actually post back to the server.

  2. If you add class mousetrap to a text input then it will allow it to receive keyboard shortcuts. You could then check e.target in your callback to see if it came from that textarea. This would look something like this:

    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');
        }
    });
    
  3. You could overwrite the Mousetrap.stopCallback function to achieve this. This is not the prettiest solution, but should work.

    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');
    });
    

I am looking into different ways I can support different scopes/contexts in Mousetrap so hopefully there will be an easier way in the future.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top