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?
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?
Share Improve this question asked Dec 23, 2019 at 10:41 KoronagKoronag 1672 silver badges16 bronze badges 2- With keyboard interactions such as openlayers/en/latest/apidoc/… and openlayers/en/latest/apidoc/… there can be issues related to which element has focus. The simplest solution might be to use the document as in this example openlayers/en/latest/examples/magnify.html – Mike Commented Dec 23, 2019 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 Commented Dec 23, 2019 at 11:25
3 Answers
Reset to default 2As 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./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
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.
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(),
],
});