1

我想製作一些自定義谷歌地圖信息窗口,但我得到的問題在我的自定義信息窗口下面的標記是可點擊的信息窗口。防止谷歌覆蓋/ infowindow允許點擊通過到下方的標記

下面是一個例子(basically straight from googles example here

<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: Info Window Custom</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 

/* An InfoBox is like an info window, but it displays 
* under the marker, opens quicker, and has flexible styling. 
* @param {GLatLng} latlng Point to place bar at 
* @param {Map} map The map on which to display this InfoBox. 
* @param {Object} opts Passes configuration options - content, 
* offsetVertical, offsetHorizontal, className, height, width 
*/ 
function InfoBox(opts) { 
    google.maps.OverlayView.call(this); 
    this.latlng_ = opts.latlng; 
    this.map_ = opts.map; 
    this.offsetVertical_ = -195; 
    this.offsetHorizontal_ = 0; 
    this.height_ = 165; 
    this.width_ = 266; 

    var me = this; 
    this.boundsChangedListener_ = 
    google.maps.event.addListener(this.map_, "bounds_changed", function() { 
     return me.panMap.apply(me); 
    }); 

    // Once the properties of this OverlayView are initialized, set its map so 
    // that we can display it. This will trigger calls to panes_changed and 
    // draw. 
    this.setMap(this.map_); 
} 

/* InfoBox extends GOverlay class from the Google Maps API 
*/ 
InfoBox.prototype = new google.maps.OverlayView(); 

/* Creates the DIV representing this InfoBox 
*/ 
InfoBox.prototype.remove = function() { 
    if (this.div_) { 
    this.div_.parentNode.removeChild(this.div_); 
    this.div_ = null; 
    } 
}; 

/* Redraw the Bar based on the current projection and zoom level 
*/ 
InfoBox.prototype.draw = function() { 
    // Creates the element if it doesn't exist already. 
    this.createElement(); 
    if (!this.div_) return; 

    // Calculate the DIV coordinates of two opposite corners of our bounds to 
    // get the size and position of our Bar 
    var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_); 
    if (!pixPosition) return; 

    // Now position our DIV based on the DIV coordinates of our bounds 
    this.div_.style.width = this.width_ + "px"; 
    this.div_.style.left = (pixPosition.x + this.offsetHorizontal_) + "px"; 
    this.div_.style.height = this.height_ + "px"; 
    this.div_.style.top = (pixPosition.y + this.offsetVertical_) + "px"; 
    this.div_.style.display = 'block'; 
}; 

/* Creates the DIV representing this InfoBox in the floatPane. If the panes 
* object, retrieved by calling getPanes, is null, remove the element from the 
* DOM. If the div exists, but its parent is not the floatPane, move the div 
* to the new pane. 
* Called from within draw. Alternatively, this can be called specifically on 
* a panes_changed event. 
*/ 
InfoBox.prototype.createElement = function() { 
    var panes = this.getPanes(); 
    var div = this.div_; 
    if (!div) { 
    // This does not handle changing panes. You can set the map to be null and 
    // then reset the map to move the div. 
    div = this.div_ = document.createElement("div"); 
    div.style.border = "0px none"; 
    div.style.position = "absolute"; 
    div.style.background = "url('http://gmaps-samples.googlecode.com/svn/trunk/images/blueinfowindow.gif')"; 
    div.style.width = this.width_ + "px"; 
    div.style.height = this.height_ + "px"; 
    var contentDiv = document.createElement("div"); 
    contentDiv.style.padding = "30px" 
    contentDiv.innerHTML = "<b>Hello World!</b>"; 

    var topDiv = document.createElement("div"); 
    topDiv.style.textAlign = "right"; 
    var closeImg = document.createElement("img"); 
    closeImg.style.width = "32px"; 
    closeImg.style.height = "32px"; 
    closeImg.style.cursor = "pointer"; 
    closeImg.src = "http://gmaps-samples.googlecode.com/svn/trunk/images/closebigger.gif"; 
    topDiv.appendChild(closeImg); 

    function removeInfoBox(ib) { 
     return function() { 
     ib.setMap(null); 
     }; 
    } 

    google.maps.event.addDomListener(closeImg, 'click', removeInfoBox(this)); 

    div.appendChild(topDiv); 
    div.appendChild(contentDiv); 
    div.style.display = 'none'; 
    panes.floatPane.appendChild(div); 
    this.panMap(); 
    } else if (div.parentNode != panes.floatPane) { 
    // The panes have changed. Move the div. 
    div.parentNode.removeChild(div); 
    panes.floatPane.appendChild(div); 
    } else { 
    // The panes have not changed, so no need to create or move the div. 
    } 
} 

/* Pan the map to fit the InfoBox. 
*/ 
InfoBox.prototype.panMap = function() { 
}; 

function initialize() { 
    var myOptions = { 
     zoom: 8, 
     center: new google.maps.LatLng(-33.397, 150.644), 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     sensor: 'true' 
    } 
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

    var marker = new google.maps.Marker({ 
     position: new google.maps.LatLng(-34, 150), 
     map: map 
    }); 
    google.maps.event.addListener(marker, "click", function(e) { 
     var infoBox = new InfoBox({latlng: marker.getPosition(), map: map}); 
    }); 

    var m2 = new google.maps.Marker({ 
     position: new google.maps.LatLng(-33.5, 150.5), 
     map: map 
    }); 
    google.maps.event.addListener(m2, "click", function(e) { 
     var infoBox = new InfoBox({latlng: m2.getPosition(), map: map}); 
    }); 

    } 
</script> 
</head> 
<body style="margin:0px; padding:0px;" onload="initialize()"> 
    <div id="map_canvas" style="width:100%; height:100%"></div> 
</body> 
</html> 

你可以看到我做兩個標記,一個只是給其他的東北部。點擊底部的一個,然後觀察其他標記如何通過標記點擊(右'W'附近)。

我該如何解決這個問題?我試過改變z-index,但似乎沒有幫助。

這是使用api v3 btw。

回答

1

對於後人來說,你想在標記彈出窗口中禁用一堆事件,這是規定的方法,即使它感覺像是過度殺傷。你也可以循環所有標記,除了單擊它們之外,並禁用點擊它們(事實上,事後看來這可能是一個更好的解決方案)。取決於你有多少標記,我有很多

東西這個(這裏沒有轉錄從我的CoffeeScript因此測試...)

// All in a google.maps.OverlayView subclass. 

... 
this.listeners = new Array(); // save listeners for unbinding later 
... 
this.cancelEvents = function(){ 
    events = ['mousedown', 'mousemove', 'mouseover', 
      'mouseout', 'mouseup', 'mousewheel', 
      'DOMMouseScroll', 'touchstart', 'touchend', 
      'touchmove', 'dblclick', 'contextmenu']; 
    // Note, don't disable 'click' if you want to be able to click links in the dom. Some things we're disabling here will can effect how your user might interact with the popup (double click to select text etc) 
    for(var i = 0; i < events.length; i++){ 
     var event = events[i]; 
     this.listeners.push(
      google.maps.event.addDomListener(
       this.popup_dom_element, 
       event, 
       function(ev){ 
        e.cancelBubble = true; 
        if(e.stopPropagation){ 
         e.stopPropagation(); 
        } 
       } 
      ); 
     ); 
    } 
} 

this.onAdd = function(){ 
    // build your html popup 
    var html_code = "..."; 
    // easy way to get a dom element but probably over kill if its your only JQ 
    this.popup_dom_element = $(html_code); 
    this.cancelEvents(); 
} 

this.onRemove = function(){ 
    // any other removal code you have 
    ... 
    for(var i = 0; i < this.listeners.length; i++){ 
     // remove our event listeners 
     google.maps.event.removeListener(this.listeners[i]); 
    } 
} 
1

如果你不希望人們能夠點擊一個標記,你可以調用marker.setClickable(false)

0

嘗試使用該MapPane overlayMouseTarget而不是floatPane

0

我有同樣的問題,它其實很容易:如果u使用/

的jQuery只需在InfoBox.prototype.createElement函數中設置

$(div).bind("click",function(e) { 
return false; 
}); 

。這應該有所幫助。

乾杯

+1

我想非JQ溶液(我不在代碼中使用jQuery,只是在給定示例中)。此外,您也可能想停止停止滾動鼠標滾輪,否則當您嘗試滾動信息框內容時,地圖會縮放。 Maps 3.7應該修復了這個問題:http://code.google.com/p/gmaps-api-issues/wiki/JavascriptMapsAPIv3Changelog http://code.google.com/p/gmaps-api-issues/issues/detail ?id = 3573 – Soup

0

使用:

google.maps.event.addDomListener

,而不是

google.maps.event.addListener

+0

歡迎來到StackOverflow。在回答問題時,請嘗試提供更多信息以幫助解釋發佈問題的人的答案。 –