1

I have a Class for simple Input-Handling like this:

class Key
{
    static enter(event, handler)
    {
        if (event.keyCode === 13) {
            $handler();
        }
    }
}

and it is called like <div onkeydown="Key.enter(event, customFunction)"></div>

I would like to be able to get the event inside of Key.enter() without always passing it to the function. I know that in a normal Function this.event would work, but this does not work, probably because Im inside a class.

Any ideas how to still get the Event that called the function so that I can call it like Key.enter(customFunction)?

Update: Made Function static, It already was in my Code, but forgot to write it in the Question.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Leander Hass
  • 162
  • 2
  • 3
  • 13
  • 1
    You need to make it a static method if you want to call it without an instance. – Barmar Aug 19 '21 at 20:53
  • You *really* shouldn't be using a `class` here. – Bergi Aug 19 '21 at 20:53
  • 1
    There's no such thing as `this.event` in a normal function. – Barmar Aug 19 '21 at 20:53
  • In a normal function, `this` is the global object, so `this.event` is the `event` global variable. That's not a standard global variable, but it works in some browsers (but not Firefox). – Barmar Aug 19 '21 at 20:55
  • Stop using inline attribute event handlers in html - see [onclick="" vs event handler](https://stackoverflow.com/q/6941483/1048572). It's easy to write a helper function that you can use as `element.onclick = onlyEnterKey(customFunction);` – Bergi Aug 19 '21 at 20:58
  • @Barmar Thanks for pointing that out, yes it actually is a static method, just forgot to put it in the Question, fixed that. Also thanks with the "this", didnt thought. I will try out window and document instead. – Leander Hass Aug 20 '21 at 13:04
  • @Bergi I know of the differences between Event-Handlers and inline Events. I use both in my projects. In this case I want to make my Site friendly for persons who use only the Keyboard to navigate and therefore inline events are much faster to code and there are way too many elements to manually assign all of them their own event-listener. – Leander Hass Aug 20 '21 at 13:07
  • @LeanderHass If you want to make your site accessible for keyboard navigation, don't use js at all, but proper semantic markup. If something should be focusable and activate on enter, that's an `` or ` – Bergi Aug 20 '21 at 14:44
  • @Bergi Well, for example i just made a pretty dropdown for language selection, you can of course navigate it with simple Tabs without JS, but I also want to enable the Esc- and Arrow-Keys to make it also a Shortcut for normal Keyboard-Users. My site as well supports users without JS but for those who do I also want it to be accessible and easy to navigate. – Leander Hass Aug 20 '21 at 14:59

1 Answers1

1

When the event handler is called, the actual event will be available as a global event variable (or as window.event, see MDN), so the event object will be accessible from the event handler, without passing it directly. In the examples below, click on a square to make it focused, and press any key. The pressed key will be printed into the log.

Note that "you should avoid using this property in new code, and should instead use the Event passed into the event handler function" (see MDN for details).

// 1. Function
function onKeyDown() {
  console.log("onKeyDown() ->", event.key);
  event.preventDefault();
}

// 2. Method
class A {
  onKeyDown() {
    console.log("new A().onKeyDown() ->", event.key);
    event.preventDefault();
  }
}

// 3. Static method
class B {
  static onKeyDown() {
    console.log("B.onKeyDown() ->", event.key);
    event.preventDefault();
  }
}
.square {
  display: inline-block;
  width: 100px;
  height: 100px;
  background: lightblue;
  text-align: center;
  vertical-align: middle;
  line-height: 100px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 10pt;
}

.square:focus {
  outline: solid 1px blue;
}
<div class="square" tabIndex="0" onkeydown="onKeyDown()">Function</div>
<div class="square" tabIndex="0" onkeydown="new A().onKeyDown()">Method</div>
<div class="square" tabIndex="0" onkeydown="B.onKeyDown()">Static Method</div>
kol
  • 27,881
  • 12
  • 83
  • 120
  • Thanks for you Reply. Although already pointed out in the Comments, replacing "this" with "window" was what I was looking for. Thanks for your effort and the big Code-Snippet though I probably wont use it. – Leander Hass Aug 20 '21 at 13:11
  • `window.event` doesn't work at all in Firefox: https://stackoverflow.com/questions/9636400/event-equivalent-in-firefox – Barmar Aug 20 '21 at 15:22