添加多个HTML标记到Google地图API

huangapple go评论52阅读模式
英文:

Adding Multiple HTML Markers to Google Maps API

问题

以下是您提供的代码部分的翻译:

function init() {

  // 左侧
  var locations = [
    ['500k', -33.890542, 151.274856, 1],
    ['1.3M', -33.923036, 151.259052, 2],
    ['2.3M', -34.028249, 151.157507, 3],
    ['750k', -33.800101, 151.287478, 4],
    ['200K', -33.950198, 151.259302, 5],
  ];

  var map = new google.maps.Map(document.getElementById('mapdiv'), {
    zoom: 10,
    center: new google.maps.LatLng(-33.92, 151.25),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  });

  var infowindow = new google.maps.InfoWindow();

  for (i = 0; i < locations.length; i++) {

    var price = locations[i][0];
    var latMarker = locations[i][1];
    var lngMarker = locations[i][2];

    function HTMLMarker(lat, lng) {
      this.lat = lat;
      this.lng = lng;
      this.pos = new google.maps.LatLng(lat, lng);
    }

    HTMLMarker.prototype = new google.maps.OverlayView();

    HTMLMarker.prototype.onRemove = function() {}

    // 初始化您的 HTML 元素
    HTMLMarker.prototype.onAdd = function() {
      div = document.createElement('div');
      div.className = "arrow_box d-flex";
      div.innerHTML = "<div class='m-auto'>SR " + price + "</div>";
      var panes = this.getPanes();
      panes.overlayImage.appendChild(div);
    }

    HTMLMarker.prototype.draw = function() {
      var overlayProjection = this.getProjection();
      var position = overlayProjection.fromLatLngToDivPixel(this.pos);
      var panes = this.getPanes();
      panes.overlayImage.style.left = position.x + 'px';
      panes.overlayImage.style.top = position.y - 30 + 'px';
    }

    // 使用它
    var htmlmarker = new HTMLMarker(latMarker, lngMarker);

    htmlmarker.setMap(map);

  }

}
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#mapdiv {
  height: 100%;
  width: 100%;
}

#mapdiv2 {
  height: 100%;
  width: 100%;
}

div.arrow_box {
  font-size: 10px;
  width: 60px;
  height: 20px;
  background: blue;
  border-radius: 10px;
  margin: 10px -30px;
  color: white;
  cursor: pointer;
  overflow: hidden;
}

div.arrow_box img {
  min-width: 150px;
  width: auto;
  max-height: 100px;
  height: auto;
  border-radius: 5px;
}

.arrow_box:after {
  top: 30px;
  left: 0px;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
  border-color: rgba(136, 183, 213, 0);
  border-top-color: blue;
  border-width: 5px;
  margin-left: -5px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">

  <title>地图测试</title>
</head>
<style>

</style>

<body class="bg-dark d-flex p-1" onload="init()">

  <div class="border border-primary bg-dark rounded" id="mapdiv">
  </div>

</body>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous">
</script>

<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>

</html>

请注意,上述代码的翻译只包括HTML、CSS和JavaScript的部分,不包括代码中的注释。

英文:

I've been trying to add multiple HTML markers on Google Maps so I can add CSS styles and also include text inside it and also animate the markers as you zoom in and out so I can make them smaller or bigger or turn them into a dot depending on the zoom level or add icons.

The style that I am trying to achieve is shown in this following example.

添加多个HTML标记到Google地图API

I've tried my best but the best I could muster up without critical errors is this following, for some reason they are stacking in one marker:

添加多个HTML标记到Google地图API

Here is the code I got.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function init() {
// LEFT
var locations = [
[&#39;500k&#39;, -33.890542, 151.274856, 1],
[&#39;1.3M&#39;, -33.923036, 151.259052, 2],
[&#39;2.3M&#39;, -34.028249, 151.157507, 3],
[&#39;750k&#39;, -33.800101, 151.287478, 4],
[&#39;200K&#39;, -33.950198, 151.259302, 5],
];
var map = new google.maps.Map(document.getElementById(&#39;mapdiv&#39;), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
var infowindow = new google.maps.InfoWindow();
for (i = 0; i &lt; locations.length; i++) {
var price = locations[i][0];
var latMarker = locations[i][1];
var lngMarker = locations[i][2];
function HTMLMarker(lat, lng) {
this.lat = lat;
this.lng = lng;
this.pos = new google.maps.LatLng(lat, lng);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function() {}
//init your html element here
HTMLMarker.prototype.onAdd = function() {
div = document.createElement(&#39;div&#39;);
div.className = &quot;arrow_box d-flex&quot;;
div.innerHTML = &quot;&lt;div class=&#39;m-auto&#39;&gt;SR &quot; + price + &quot;&lt;/div&gt;&quot;;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
}
HTMLMarker.prototype.draw = function() {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var panes = this.getPanes();
panes.overlayImage.style.left = position.x + &#39;px&#39;;
panes.overlayImage.style.top = position.y - 30 + &#39;px&#39;;
}
// to use it
var htmlmarker = new HTMLMarker(latMarker, lngMarker);
htmlmarker.setMap(map);
}
}

<!-- language: lang-css -->

html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#mapdiv {
height: 100%;
width: 100%;
}
#mapdiv2 {
height: 100%;
width: 100%;
}
div.arrow_box {
font-size: 10px;
width: 60px;
height: 20px;
background: blue;
border-radius: 10px;
margin: 10px -30px;
color: white;
cursor: pointer;
overflow: hidden;
}
div.arrow_box img {
min-width: 150px;
width: auto;
max-height: 100px;
height: auto;
border-radius: 5px;
}
.arrow_box:after {
top: 30px;
left: 0px;
border: solid transparent;
content: &quot; &quot;;
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(136, 183, 213, 0);
border-top-color: blue;
border-width: 5px;
margin-left: -5px;
}

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD&quot; crossorigin=&quot;anonymous&quot;&gt;
&lt;title&gt;Map Test&lt;/title&gt;
&lt;/head&gt;
&lt;style&gt;
&lt;/style&gt;
&lt;body class=&quot;bg-dark d-flex p-1&quot; onload=&quot;init()&quot;&gt;
&lt;div class=&quot;border border-primary bg-dark rounded&quot; id=&quot;mapdiv&quot;&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;script src=&quot;https://maps.googleapis.com/maps/api/js?v=3.exp&amp;sensor=false&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js&quot; integrity=&quot;sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN&quot; crossorigin=&quot;anonymous&quot;&gt;
&lt;/script&gt;
&lt;script src=&#39;https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js&#39;&gt;&lt;/script&gt;
&lt;/html&gt;

<!-- end snippet -->

答案1

得分: 2

以下是您的代码中提到的问题的翻译:

  • 无需在for循环内声明HTMLMarker函数。将其声明在循环外部,然后在循环内调用new HTMLMarker(...)setMap()函数。
  • 我已经在create函数中添加了价格,因此您可以将其作为this.price引用,并在onAdd函数中使用它。
  • 同样适用于您正在创建的div。使用this.div = document.createElement('div');,以便您可以在其他函数中引用它。
  • 我使用了overlayMouseTarget,这似乎比overlayImage更适合保存HTML标记。
  • draw()函数中,设置this.div的位置,而不是设置整个地图窗格的位置。
  • 最后但并非最不重要的,您的.arrow_box元素需要position: absolute;

还有一些事情:

  • <script>标签包含在<body>元素内
  • 在API调用&callback=init中将您的地图初始化函数init()声明为回调,并使用defer属性确保回调在浏览器完全解析DOM后执行
  • init()函数声明为window对象的属性
  • 我修复了您的CSS,如果在框上有overflow: hidden;,箭头无法显示,您需要正确的topleft
  • 鉴于您的框设计,如果要箭头的尖端位于确切的坐标上,您需要将draw()函数中的this.div.style.top值偏移35px,即this.div.style.top = (position.y - 35)
  • 查看高级标记,但它仍处于预览(pre-GA)状态。

希望这些翻译对您有所帮助。如果您有其他问题或需要进一步的翻译,请随时提问。

英文:

There are several issues with your code.

  • There is no need to declare the HTMLMarker functions within the for loop. Declare it outside and call the new HTMLMarker(...) and setMap() function within the loop.
  • I have added the price in the create function so you can refer to it as this.price and use it that way in the onAdd function.
  • The same goes for the div you are creating. Use this.div = document.createElement(&#39;div&#39;); so you can refer to it in other functions.
  • I have used overlayMouseTarget which seems more appropriate than overlayImage for holding HTML markers.
  • In the draw() function, set the position of this.div instead of setting the position of the entire map pane.
  • Last but not least, your .arrow_box elements need to be position: absolute;

A few more things:

  • Include &lt;script&gt; tags within the &lt;body&gt; element
  • Declare your map initialization function init() as a callback in the api call &amp;callback=init and use defer attribute to make sure the callback executes after the full DOM was parsed by the browser
  • Declare the init() function as a property of the window object
  • I fixed your CSS, the arrows can't display if you have overflow: hidden; on the box and you need correct top and left values
  • Given your box design, you need to offset the top value by 35px this.div.style.top = (position.y - 35) in the draw() function if you want the tip of the arrow to be on the exact coordinates
  • Have a look at Advanced Markers but it is still in Preview (pre-GA)

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

function init() {
var locations = [
[&#39;500k&#39;, -33.890542, 151.274856, 1],
[&#39;1.3M&#39;, -33.923036, 151.259052, 2],
[&#39;2.3M&#39;, -34.028249, 151.157507, 3],
[&#39;750k&#39;, -33.800101, 151.287478, 4],
[&#39;200K&#39;, -33.950198, 151.259302, 5],
];
var map = new google.maps.Map(document.getElementById(&#39;mapdiv&#39;), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
function HTMLMarker(lat, lng, price) {
this.price = price;
this.pos = new google.maps.LatLng(lat, lng);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function() {}
HTMLMarker.prototype.onAdd = function() {
this.div = document.createElement(&#39;div&#39;);
this.div.className = &quot;arrow_box d-flex&quot;;
this.div.innerHTML = &quot;&lt;div class=&#39;m-auto&#39;&gt;SR &quot; + this.price + &quot;&lt;/div&gt;&quot;;
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(this.div);
}
HTMLMarker.prototype.draw = function() {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
this.div.style.left = position.x + &#39;px&#39;;
this.div.style.top = (position.y - 35) + &#39;px&#39;;
}
for (let i = 0; i &lt; locations.length; i++) {
let htmlMarker = new HTMLMarker(locations[i][1], locations[i][2], locations[i][0]);
htmlMarker.setMap(map);
}
}
window.init = init;

<!-- language: lang-css -->

html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#mapdiv {
height: 200px;
width: 100%;
}
.arrow_box {
position: absolute;
font-size: 10px;
width: 60px;
height: 20px;
background: blue;
border-radius: 10px;
margin: 10px -30px;
color: white;
cursor: pointer;
}
.arrow_box img {
min-width: 150px;
width: auto;
max-height: 100px;
height: auto;
border-radius: 5px;
}
.arrow_box:after {
top: 20px;
left: 50%;
border: solid transparent;
content: &quot; &quot;;
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(136, 183, 213, 0);
border-top-color: blue;
border-width: 5px;
margin-left: -5px;
}

<!-- language: lang-html -->

&lt;link href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD&quot; crossorigin=&quot;anonymous&quot;&gt;
&lt;div id=&quot;mapdiv&quot;&gt;&lt;/div&gt;
&lt;!-- 
The `defer` attribute causes the callback to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises
with https://www.npmjs.com/package/@googlemaps/js-api-loader.
--&gt;
&lt;script src=&quot;https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&amp;callback=init&quot; defer&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月7日 20:20:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661905.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定