javascript - 谷歌地图不会放弃在 shadow DOM 中输入的按键

标签 javascript google-maps google-maps-api-3 shadow-dom

对于重现代码的长度,我们深表歉意。问题是谷歌地图 API 似乎不会将某些按键转发到影子 DOM 中的元素。如果您加载以下代码(提供您自己的 API key ),使用箭头键平移 map ,然后尝试在屏幕顶部输入内容,您会看到“m”、“k”和箭头键(至少)不要输入。奇怪的是,这些键的 keypresskeydown 事件会在输入时触发,但重要的是,input 不会触发。尽管 map 不再具有焦点,但箭头键仍然能够平移 map 。输入底部输入(在常规 DOM 中)按预期工作。

注意:

  1. 如果您不使用箭头键平移 map ,输入将按预期工作。
  2. 如果您不将输入放在影子 DOM 中,它会按预期工作。

所以问题似乎是,一旦 map 获得键盘焦点,它就拒绝放弃它。我尝试为 div 提供 tabindexfocus 输入。不解决问题。

<!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/

相关文章:

javascript - Meteor - 插入对象数组

google-maps - 获取 Google Maps JavaScript API v3 中的当前位置并在无需用户交互的情况下获取关注点

api - 谷歌地图 API 与谷歌地图引擎?

javascript - Google Maps API v3 的 {directionsService} API 存在问题

javascript - 为什么javascript将1添加到setInterval id?

javascript - 正则表达式排除 URL

javascript - Bootstrap 4 : when navbar is collapsed li item is displayed horizontally next to navbar-brand

javascript - 点击链接时谷歌地图平移到中心

android - 在谷歌地图中使用可组合而不是标记?

javascript - 使用 google-map api 仅使用确切位置填充文本框