3

I'm unable to add a custom keyboard-event to Openlayers, and can't figure out why. Might it be a bug in relation to the already existing keyboard-events included in Openlayers?

I've tried the following with no result:

this.map.getViewport().addEventListener('keydown', (e) => {
  console.log(e);
}, true)


document.getElementById('map').addEventListener('keydown', (e) => {
  console.log(e);
})

Listening to clicks on the same elements work fine:

this.map.getViewport().addEventListener('click', (e) => {
  console.log(e);
}, true)

document.getElementById('map').addEventListener('click', (e) => {
  console.log(e);
})

Any solutions to this?

Koronag
  • 157
  • 1
  • 15
  • With keyboard interactions such as https://openlayers.org/en/latest/apidoc/module-ol_interaction_KeyboardPan-KeyboardPan.html and https://openlayers.org/en/latest/apidoc/module-ol_interaction_KeyboardZoom-KeyboardZoom.html there can be issues related to which element has focus. The simplest solution might be to use the document as in this example https://openlayers.org/en/latest/examples/magnify.html – Mike Dec 23 '19 at 11:20
  • Thanks @Mike, unfortunately i cannot listen to the whole document in this case. I work in angular, and we have forms rendered at the same time as the map, so it can make things tricky. Would really like to restrict it just to the map itself. Will investigate further to see if i can find a way around this. – Koronag Dec 23 '19 at 11:25

3 Answers3

2

This problem as Mike mentioned is occurring because of focus issues.
I faced this problem a few months ago, so I searched my old projects and find this:

<div id="map" tabindex="0"></div>

After assigning a tab index to an element you can use javascript focus(). in order to use it (after assigning tab index) use this:

document.getElementById('map').focus();

I think this could help.
Also, there is an answer I found months ago is here. You can find more info about focusing.

Mahdi Mahmoodian
  • 473
  • 2
  • 13
2

As mentioned map needs focus. You can use the FocusMap interaction of ol-ext to focus on the map when ckick on it.

See https://github.com/Viglino/ol-ext/blob/master/src/interaction/FocusMap.js

This example use it to handle ctrl+c/ctrl+v on a map. https://viglino.github.io/ol-ext/examples/interaction/map.interaction.copypaste.html

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
Viglino Jean-Marc
  • 1,371
  • 8
  • 6
1

The most reliable solution in our angular application was to add a custom Interaction, but you still need to set tabindex="0" on your map ;)

<div class="map" tabindex="0" id="map"></div>

Here is an example:

import { Interaction } from "ol/interaction";
import { MapBrowserEvent } from "ol";

class KeyboardEventInteraction extends Interaction {
  constructor() {
    super();
  }
  handleEvent(mapBrowserEvent: MapBrowserEvent<KeyboardEvent>) {
    let stopEvent = false;
    if (mapBrowserEvent.type === "keydown") {
      const keyEvent = mapBrowserEvent.originalEvent;
      if (keyEvent.code?.toLowerCase() === "escape") {
        // do whatever you want with your escape key
        stopEvent = true;
      }
      // add other keys
      if (stopEvent) {
        keyEvent.preventDefault();
      }
    }
    return !stopEvent;
  }
}

You need to add this handler to your map:

new Map({
  //... your map settings
  interactions: [
    //... your interactions
    new KeyboardEventInteraction(),
  ],
});
thegnuu
  • 697
  • 6
  • 9