对于重现代码的长度,我们深表歉意。问题是谷歌地图 API 似乎不会将某些按键转发到影子 DOM 中的元素。如果您加载以下代码(提供您自己的 API key ),使用箭头键平移 map ,然后尝试在屏幕顶部输入内容,您会看到“m”、“k”和箭头键(至少)不要输入。奇怪的是,这些键的 keypress
和 keydown
事件会在输入时触发,但重要的是,input
不会触发。尽管 map 不再具有焦点,但箭头键仍然能够平移 map 。输入底部输入(在常规 DOM 中)按预期工作。
注意:
- 如果您不使用箭头键平移 map ,输入将按预期工作。
- 如果您不将输入放在影子 DOM 中,它会按预期工作。
所以问题似乎是,一旦 map 获得键盘焦点,它就拒绝放弃它。我尝试为 div 提供 tabindex
和 focus
输入。不解决问题。
<!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>
最佳答案
这是一个 bug in the google maps API .我临时解决了它,如下所示:
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);
});
基本上我禁用 map API 键盘处理并替换我自己的键盘。您可以调整箭头键上的平移值以实现更平滑的滚动,但我现在已经超时了。
关于javascript - 谷歌地图不会放弃在 shadow DOM 中输入的按键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48893262/