Reputation: 21965
Sorry for the length of the code to reproduce. The problem is that the google maps API seems to not forward certain key presses to an element in shadow DOM. If you load the following code (supplying your own API key), pan the map with the arrow keys, then try to type in the top input on the screen you'll see that the 'm', 'k', and arrow keys (at least) do not make it to the input. Strangely, the keypress
and keydown
events for those keys get triggered on the input, but not, importantly, input
. The arrow keys continue to be able to pan the map despite it no longer having focus. Typing into the bottom input (in regular DOM) works as expected.
NOTE:
So the problem seems to be that once the map gets keyboard focus it refuses to relinquish it. I tried giving the div with the input a tabindex
and focus
ing it. Does not resolve the problem.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0">
<meta charset="utf-8"/>
<style>
html, body {
font-family: sans-serif;
width: 100%;
height: 100%;
margin: 0;
}
#map-div {
width: 100%;
height: 100%;
}
#shadow {
position: fixed;
top: 50px;
left: 50px;
z-index: 1000;
}
#input {
position: fixed;
top: 100px;
left: 50px;
z-index: 1000;
}
</style>
</head>
<body>
<div id="shadow"></div>
<input id="input"></input>
<div id="map-div"></div>
<script>
document.querySelector('#shadow')
.attachShadow({mode:'open'})
.appendChild(document.createElement('input'));
window._mapsLoaded = () => {
let map = new google.maps.Map(document.querySelector('#map-div'), {
center: new google.maps.LatLng(39.75, -86.16),
zoom: 11,
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=$API_KEY&callback=_mapsLoaded"></script>
</body>
</html>
Upvotes: 4
Views: 472
Reputation: 21965
This is a bug in the google maps API. I have temporarily worked around it as follows:
let mapDiv = document.querySelector('#map-div');
let map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(39.75, -86.16),
zoom: 11,
keyboardShortcuts: false, // disables the API keyboard handlers
});
// The added cases on the arrows are to cope with Edge's
// non-standard key values
let keymap = key => {
switch (key) {
case 'ArrowUp':
case 'Up':
return 38;
case 'ArrowDown':
case 'Down':
return 40;
case 'ArrowLeft':
case 'Left':
return 37;
case 'ArrowRight':
case 'Right':
return 39;
case 'Add':
case 'Equal':
return 187;
case 'Minus':
case 'Subtract':
return 189;
default: return 0; // browsers give keyCode 0 for unknown
}
};
let keydownHandler = e => {
let value = e.keyCode || keymap(e.key);
switch (value) {
case 107: // numpad add
case 187: // equals/plus
map.setZoom(map.getZoom() + 1);
break;
case 109: // numpad subtract
case 189: // minus
map.setZoom(map.getZoom() - 1);
break;
case 37: // left
map.panBy(-50, 0);
break;
case 38: // up
map.panBy(0, 50);
break;
case 39: // right
map.panBy(50, 0);
break;
case 40: // down
map.panBy(0, -50);
break;
}
};
// Here we'll track keydowns only when the mouse is over
// the map container:
mapDiv.addEventListener('mouseenter', e => {
document.addEventListener('keydown', keydownHandler);
});
mapDiv.addEventListener('mouseleave', e => {
document.removeEventListener('keydown', keydownHandler);
});
Basically I disable the maps API keyboard handling and substitute my own. You can adjust the pan values on the arrow keys for smoother scrolling, but I've timed out on this for now.
Upvotes: 3
Reputation: 426
As workaround you can go to the input's location on the dom document using the window.location
method. I've modified your sample to by adding an onfocus
event to the #shadow
input.
<script>
document.querySelector('#shadow')
.attachShadow({mode:'open'})
.appendChild(document.createElement('input'));
window._mapsLoaded = () => {
let map = new google.maps.Map(document.querySelector('#map-div'), {
center: new google.maps.LatLng(39.75, -86.16),
zoom: 11,
});
}
function focusOnShadow() {
window.location.hash = '#tries';
}
</script>
Here is the working sample on jsfiddle.
Update: I see that I've only managed to fix the 'm' and 'k' problem but the arrow key behavior persists.
Upvotes: 1