【问题标题】:Google maps listener event acts like a click even though it is a mouseover谷歌地图侦听器事件就像点击一样,即使它是鼠标悬停
【发布时间】:2014-07-15 19:19:28
【问题描述】:

我正在添加这两个 google.maps.event.addListener 事件

google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
   markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});
google.maps.event.addListener(markerAcademicCenter, "mouseout", function (e) {
   markerIconAcademicCenter.url = 'MapIcons/Circle64.png'
});

在这个标记下方已经有一个点击事件。

google.maps.event.addListener(markerAcademicCenter, "click", function (e) {
   $(".campusMapInfoPanel > div").appendTo($(".InfoStorageDiv"));
   $(".InfoPanelAcademicCenter").appendTo($(".campusMapInfoPanel"));
   this.setZIndex(google.maps.Marker.MAX_ZINDEX + 1);
   setZoomWhenMarkerClicked();
   CampusMap.setCenter(markerAcademicCenter.getPosition());
});

markerIconAcademicCenter.url 已在这些事件上方设置为 Circle64。我希望页面加载更大的圆圈 - 64x64 - 当我悬停并离开标记区域时来回切换。

我有两个问题

  1. 当我将鼠标悬停在标记上时没有任何反应,但当我单击时却发生了。在页面加载后首次单击时,地图会缩放并以建筑物为中心,并且标记图像会调整大小。如果我再次单击该建筑物,则不会发生其他任何事情,但是:
  2. 如果我单击触发 click 事件的菜单链接,function buildingFocus(markerName) {google.maps.event.trigger(markerName, "click");} 该函数会重置图标,就像它是 mouseout 事件一样。

为了进一步测试这种意外行为,我一次注释掉每个事件。为了澄清实际发生的事情,我首先将初始图像更改为 clear.png。

当我取出鼠标悬停事件时,当我在页面加载后第一次单击建筑事件或菜单链接时,图像没有改变。在我删除 mouseover 事件之前,在页面加载后第二次单击时单击菜单会将图标更改为 mouseout 图像,但现在单击建筑物会导致这种情况。

当我取出 mouseout 事件时,在第一次单击时单击建筑物会使图标变为鼠标悬停图像,然后再次单击任一区域都没有进一步的作用。如果我在第一次或以后点击菜单链接时点击了菜单链接,图像并没有改变,但是当我点击建筑物时它就改变了。

当我取出点击事件时,图像从未改变。就其本身而言,click 事件在两个位置都按预期工作。

【问题讨论】:

  • 什么是markerIconAcademicCenter?
  • 它是一个包含学术中心标记的 url、大小、来源和锚点信息的对象。

标签: javascript jquery google-maps-api-3


【解决方案1】:

标记的图标不是MVCObject,API不会观察图标属性的变化。

您必须修改图标的url,然后调用setIcon 以应用更改:

google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
  var icon = this.getIcon();
  icon.url =  'url/to/icon';
  this.setIcon(icon);
});

但我不建议这样做,当您将图标用于多个标记时,更改url(或其他属性)会影响原始图标markerIconAcademicCenter(标记使用对原始对象的引用)。您最好使用修改后的 url 创建一个副本:

google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
  var icon = this.getIcon(),copy={};
     for(var k in icon){
      copy[k]=icon[k];
     }
  copy.url=  'url/to/icon';     
  this.setIcon(copy);
});

【讨论】:

  • 啊。您是否从经验中知道这一点,或者有什么地方我可以去研究为什么以及何时在其他地方使用这种技术?第二个问题,这仅在我将鼠标悬停在建筑物上时才有效,而不是菜单链接。编辑:没关系。我明白了。
  • 使用副本代替真实物品的技术。我唯一一次使用过类似的东西是在课堂上的 Pass-by-value 和 Pass-by-pointer 课程。
  • 当您需要继承某些属性但又必须修改对象的某些属性而不修改原始对象时,您将始终使用它。
【解决方案2】:

试试这个:

google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
   markerIconAcademicCenter.setIcon('url to icon');
});

而不是下面的代码:

google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
   markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});

这将解决您在鼠标悬停和鼠标悬停问题上更改图标大小的问题。

【讨论】:

  • 如果我没看错,你认为我不想改变尺寸吗?
  • 这不仅仅是改变大小,如果你使用相同的不同比例的图标会出现大小变化,但这只是改变应用事件的图标。
  • 对不起,我还是不明白这样做的好处。能举个详细的例子吗?
【解决方案3】:

你可以查看下面的代码,这样你就清楚我的意思了:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=places"></script>
<script type="text/javascript">

  var map, places, iw;
  var markers = [];
  var autocomplete;
  var options = {
        //types: ['(cities)'],
        //componentRestrictions: {country: 'us'}
    };
  var geocoder = new google.maps.Geocoder();
  function initialize() {
    var myLatlng = new google.maps.LatLng(37.783259, -122.402708);
    var myOptions = {
      zoom: 12,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    places = new google.maps.places.PlacesService(map);
    google.maps.event.addListener(map, 'tilesloaded', tilesLoaded);
    autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'), options);
    google.maps.event.addListener(autocomplete, 'place_changed', function() {
      showSelectedPlace();
    });
  }

  function tilesLoaded() {
    google.maps.event.clearListeners(map, 'tilesloaded');
    google.maps.event.addListener(map, 'zoom_changed', search);
    google.maps.event.addListener(map, 'dragend', search);
    search();
  }

  function showSelectedPlace() {
    clearResults();
    clearMarkers();
    var place = autocomplete.getPlace();
    map.panTo(place.geometry.location);
    markers[0] = new google.maps.Marker({
      position: place.geometry.location,
      map: map
    });
    iw = new google.maps.InfoWindow({
      content: getIWContent(place)
    });
    iw.open(map, markers[0]);
    search();
  }

  function search() {
    var type;
    for (var i = 0; i < document.controls.type.length; i++) {
      if (document.controls.type[i].checked) {
        type = document.controls.type[i].value;
      }
    }

    autocomplete.setBounds(map.getBounds());

    var search = {
      bounds: map.getBounds()
    };

    if (type != 'establishment') {
      search.types = [ type ];
    }

    places.search(search, function(results, status) {
      if (status == google.maps.places.PlacesServiceStatus.OK) {
        clearResults();
        clearMarkers();
        for (var i = 0; i < 9; i++) {
          markers[i] = new google.maps.Marker({
            position: results[i].geometry.location,
            animation: google.maps.Animation.DROP
          });

          google.maps.event.addListener(markers[i], 'mouseover', animate(i));
          google.maps.event.addListener(markers[i], 'mouseout', reanimate(i));
          google.maps.event.addListener(markers[i], 'click', getDetails(results[i], i));
          setTimeout(dropMarker(i), i * 100);
          //addResult(results[i], i);
          mygetDetails(results[i], i);
        }
      }
    })
  }

  function clearMarkers() {
    for (var i = 0; i < markers.length; i++) {
      if (markers[i]) {
        markers[i].setMap(null);
        markers[i] == null;
      }
    }
  }

  function dropMarker(i) {
    return function() {
      markers[i].setMap(map);
    }
  }

  //Function to animate markers on there hover
    function animate(locationCount){
        return function(){ 
            markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2');
            $("#addressSpan"+locationCount).css('font-weight', '700');
            $("#addressSpan"+locationCount).css('color', '#ff0000');
        }
    }

    //Function to remove animation of markers on there hover
    function reanimate(locationCount){ 
        return function(){ 
            markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=1');
            $("#addressSpan"+locationCount).css('font-weight', '');
            $("#addressSpan"+locationCount).css('color', '');
        }
    }

  function addResult(result, i) {

    if(i<=9){
        var results = document.getElementById("results");
        var tr = document.createElement('tr');
        tr.style.backgroundColor = (i% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
        tr.click = function() {
        google.maps.event.trigger(markers[i], 'click');
        };

        var iconTd = document.createElement('td');
        var nameTd = document.createElement('td');
        var addressTd = document.createElement('td');
        var icon = document.createElement('img');
        icon.src = result.icon;
        icon.setAttribute("class", "placeIcon");
        icon.setAttribute("className", "placeIcon");
        var name = document.createTextNode(result.name);
        var address = document.createTextNode(result.formatted_address);

        iconTd.appendChild(icon);
        nameTd.appendChild(name);
        addressTd.appendChild(address);
        tr.appendChild(iconTd);
        tr.appendChild(nameTd);
        tr.appendChild(addressTd);
        results.appendChild(tr);
    }
  }

  function clearResults() {
    var results = document.getElementById("results");
    while (results.childNodes[0]) {
      results.removeChild(results.childNodes[0]);
    }
  }

  function clearResults1() {
    var results = document.getElementById("results1");
    while (results.childNodes[0]) {
      results.removeChild(results.childNodes[0]);
    }
  }

  function getDetails(result, i) {
    return function() {
      places.getDetails({
          reference: result.reference
      }, showInfoWindow(i));
    }
  }

  function mygetDetails(result, i) {
    return places.getDetails({
          reference: result.reference
      }, function(place, status){
            if (status == google.maps.places.PlacesServiceStatus.OK) {
                addResult(place, i);
            }
         });
  }

  function showInfoWindow(i) {
    return function(place, status) {
      if (iw) {
        iw.close();
        iw = null;
      }

      if (status == google.maps.places.PlacesServiceStatus.OK) {
        iw = new google.maps.InfoWindow({
          content: getIWContent(place)
        });
        iw.open(map, markers[i]);        
      }
    }
  }

  function getIWContent(place) {
    var content = "";
    content += '<table><tr><td>';
    content += '<img class="placeIcon" src="' + place.icon + '"/></td>';
    content += '<td><b><a href="' + place.url + '">' + place.name + '</a></b>';
    content += '</td></tr></table>';
    return content;
  }

  $(function(){
        $("#autocomplete").keyup(function(){
            clearResults1();
            geocoder.geocode({"address": $(this).val()}, function(data, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    $.each(data, function(int_index,value) {
                        var results = document.getElementById("results1");
                        var tr = document.createElement('tr');
                        tr.style.backgroundColor = (int_index% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
                        var nameTd = document.createElement('td');
                        var name = document.createTextNode(value.formatted_address);
                        nameTd.appendChild(name);
                        tr.appendChild(nameTd);
                        results.appendChild(tr);
                    });
                }
            });
        });
    });
</script>
<style>
body {
  font-family: sans-serif;
}
#map_canvas {
  position: absolute;
  width: 399px;
  height: 399px;
  top: 25px;
  left: 0px;
  border: 1px solid grey;
}
#listing {
  position: absolute;
  width: 200px;
  height: 360px;
  overflow: auto;
  left: 401px;
  top: 65px;
  cursor: pointer;
}
#listing1 {
  position: absolute;
  width: 200px;
  height: 360px;
  overflow: auto;
  left: 601px;
  top: 65px;
  cursor: pointer;
}
#controls {
  width: 200px;
  position: absolute;
  top: 0px;
  left: 400px;
  height: 60px;
  padding: 5px;
  font-size: 12px;
}
.placeIcon {
  width: 16px;
  height: 16px;
  margin: 2px;
}
#resultsTable, #resultsTable1{
  font-size: 10px;
  border-collapse: collapse;
}
#locationField {
  width: 400px;
  height: 25px;
  top: 0px;
  left: 0px;
  position: absolute;
}
#autocomplete {
  width: 400px;
}
</style>
</head>
<body style="margin:0px; padding:0px;" onLoad="initialize()">
  <div id="locationField">
    <input id="autocomplete" type="text" />
  </div>
  <div id="controls">
    <form name="controls">
    <input type="radio" name="type" value="establishment" onClick="search()" checked="checked"/>All<br/>
    <input type="radio" name="type" value="restaurant" onClick="search()" />Restaurants<br/>
    <input type="radio" name="type" value="lodging" onClick="search()" />Lodging
    </form>
  </div>
  <div id="map_canvas"></div>
  <div id="listing"><table id="resultsTable"><tr><td><h3>Suggested<br>Locations</h3></td></tr><tbody id="results"></tbody></table></div>
  <div id="listing1"><table id="resultsTable1"><tr><td><h3>Suggested<br>Address</h3></td></tr><tbody id="results1"></tbody></table></div>
</body>
</html>

这是一个工作示例。

【讨论】:

  • 感谢您的努力。正如我所问的,它肯定更详细,但它太复杂了。根据我辅导大学生的经验,最好让解释尽可能简单。 (见上面莫勒博士的回答)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
  • 1970-01-01
  • 2021-09-06
  • 1970-01-01
  • 2012-10-16
相关资源
最近更新 更多