简体   繁体   English

标记Google地图的动态图标更改

[英]dynamic icon change for markers google maps

I have studied the map class from Google and got to point where I'm able to set markers on locations I want. 我研究了Google的地图类,并指出了我可以在所需位置设置标记的地方。 I wanted to have icons dynamically updated on "mouse events" 我想让图标在“鼠标事件”中动态更新

    var neighborhoods = [
    [54.50266744485844,  18.540940856933616],
    [54.49848076437959,  18.540254211425804],
    [54.49190082846816, 18.518968200683616],
    [54.4040671009359,  18.608918762207054],
    ];

    var markers = [];
    var map;

And for to put markers I use function as below. 对于标记,我使用以下功能。

     function setMarkers(map) {

      var image = {
      url: '/images/icon1.png',
   anchor: new google.maps.Point(0, 32)
   };
    var shape = {
    coords: [1, 1, 1, 20, 18, 20, 18, 1],
    type: 'poly'
  };


    for (var i = 0; i < neighborhoods.length; i++) 
       {
        var neighborhood = neighborhoods[i];
        var marker_temp = new google.maps.Marker
        ({
        position: {lat: neighborhood[0], lng: neighborhood[1]},
        map: map,
        icon: image,
        shape: shape,
        title: "",
        visible:true,
        zIndex: 3
        });
        marker_temp.addListener('mouseover', function() 
        { 
        marker_temp.setOptions({icon: "/images/icon1.png"});
        });

        marker_temp.addListener('mouseout',  function() 
        { 
        marker_temp.setOptions({icon: "/images/icon2.png"});    
        });

        marker_temp.addListener('click',  function() 
        { 
        marker_temp.setOptions({icon: "/images/icon1.png"});
        });


    markers.push(marker_temp);
}// end of for loop ----------------------------------------------------

     }// --- end of set markers function --------------------------------

Putting markers works fine and events on all of them are triggered as expected but only change of the icon from icon1.png to icon2.png works on last marker with events related to all fo them. 放置标记可以正常工作,并且所有标记上的事件均会按预期触发,但是只有将图标从icon1.png更改为icon2.png才能在最后一个标记上起作用,并且事件与所有标记相关。 Can anyone tell me where is error in my thinking ? 谁能告诉我我的思想错误在哪里?

Javascript does not have block scope, but function scope. Javascript没有块范围,但是有函数范围。 Example: 例:

function setMarkers(map) {
....
   for (var i = 0; i < neighborhoods.length; i++) 
   {
    ....
    var marker_temp = new google.maps.Marker
    ....
   }
}

The variable marker_temp is scoped to the function setMarkers , not to the for -loop as is usual in other programming languages. 变量marker_temp的作用域为setMarkers函数,而不是其他编程语言中常见的for -loop范围。

The above is functionally the same as this (the process is called hoisting ): 上面的功能与此相同(该过程称为hoisting ):

function setMarkers(map) {
    var marker_temp;
    ....
    for (var i = 0; i < neighborhoods.length; i++) 
    {
     ....
     marker_temp = new google.maps.Marker
     ....
   }
}

That means that when you do this: 这意味着当您执行此操作时:

marker_temp.addListener('click',  function() 
{ 
    marker_temp.setOptions({icon: "/images/icon1.png"});
});

When you call setOptions , the marker_temp variable will be the value that was last set in the loop. 调用setOptionsmarker_temp变量将是循环中最后设置的值。

To circumvent the problem you can use an IIFE (inmediately invoked function expression) so you can capture the value of marker variable at that point in time: 要解决该问题,可以使用IIFE(中间调用的函数表达式),以便可以在该时间点捕获标记变量的值:

 marker_temp.addListener('click',  (function(theMarker) 
 { 
    return function(){
        theMarker.setOptions({icon: "/images/icon1.png"});
    }
 })(marker_temp));

For more information about scope and hoisting you can read a blog post I wrote about this: https://www.kenneth-truyers.net/2013/04/20/javascript-hoisting-explained/ 有关范围和吊装的更多信息,您可以阅读我写的一篇博客文章: https : //www.kenneth-truyers.net/2013/04/20/javascript-hoisting-explained/

If you are going to set a number of event listeners, I find it simpler to write a createMarker function to hold function closure on the marker for the event listeners. 如果要设置许多事件侦听器,我发现编写一个createMarker函数以在事件侦听器的标记上保留函数闭包更为简单。 Then call that from inside the loop. 然后从循环内部调用它。 One example of a createMarker function: createMarker函数的一个示例:

function createMarker(neighborhood, idx, bounds, map) {
  var image = {
    url: 'http://maps.google.com/mapfiles/ms/micons/blue.png',
    anchor: new google.maps.Point(16, 32)
  };
  var shape = {
    coords: [1, 1, 1, 20, 18, 20, 18, 1],
    type: 'poly'
  };

  var marker_temp = new google.maps.Marker({
    position: {
      lat: neighborhood[0],
      lng: neighborhood[1]
    },
    map: map,
    icon: image,
    shape: shape,
    title: "" + idx,
    visible: true,
    // zIndex: 3
  });
  bounds.extend(marker_temp.getPosition());

  marker_temp.addListener('mouseover', function() {
    marker_temp.setOptions({
      icon: "http://maps.google.com/mapfiles/ms/micons/yellow.png",
      anchor: new google.maps.Point(16, 32)
    });
  });

  marker_temp.addListener('mouseout', function() {
    marker_temp.setOptions({
      icon: "http://maps.google.com/mapfiles/ms/micons/green.png",
      anchor: new google.maps.Point(16, 32)
    });
  });

  marker_temp.addListener('click', function() {
    marker_temp.setOptions({
      icon: "http://maps.google.com/mapfiles/ms/micons/orange.png",
      anchor: new google.maps.Point(16, 32)
    });
  });
  markers.push(marker_temp);
}

proof of concept fiddle 概念证明

code snippet: 代码段:

 function initialize() { var map = new google.maps.Map( document.getElementById("map_canvas"), { center: new google.maps.LatLng(37.4419, -122.1419), zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }); setMarkers(map); } google.maps.event.addDomListener(window, "load", initialize); function setMarkers(map) { var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < neighborhoods.length; i++) { var neighborhood = neighborhoods[i]; createMarker(neighborhood, i, bounds, map); } // end of for loop -------------------------------------- map.fitBounds(bounds); } // --- end of set markers function ------------------------ function createMarker(neighborhood, idx, bounds, map) { var image = { url: 'http://maps.google.com/mapfiles/ms/micons/blue.png', anchor: new google.maps.Point(16, 32) }; var shape = { coords: [1, 1, 1, 20, 18, 20, 18, 1], type: 'poly' }; var marker_temp = new google.maps.Marker({ position: { lat: neighborhood[0], lng: neighborhood[1] }, map: map, icon: image, shape: shape, title: "" + idx, visible: true, // zIndex: 3 }); bounds.extend(marker_temp.getPosition()); marker_temp.addListener('mouseover', function() { marker_temp.setOptions({ icon: "http://maps.google.com/mapfiles/ms/micons/yellow.png", anchor: new google.maps.Point(16, 32) }); }); marker_temp.addListener('mouseout', function() { marker_temp.setOptions({ icon: "http://maps.google.com/mapfiles/ms/micons/green.png", anchor: new google.maps.Point(16, 32) }); }); marker_temp.addListener('click', function() { marker_temp.setOptions({ icon: "http://maps.google.com/mapfiles/ms/micons/orange.png", anchor: new google.maps.Point(16, 32) }); }); markers.push(marker_temp); } var neighborhoods = [ [54.50266744485844, 18.540940856933616], [54.49848076437959, 18.540254211425804], [54.49190082846816, 18.518968200683616], [54.4040671009359, 18.608918762207054], ]; var markers = []; 
 html, body, #map_canvas { height: 100%; width: 100%; margin: 0px; padding: 0px } 
 <script src="https://maps.googleapis.com/maps/api/js"></script> <div id="map_canvas"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM