gpt4 book ai didi

javascript - CSS 谷歌地图自定义信息窗口

转载 作者:数据小太阳 更新时间:2023-10-29 05:30:51 32 4
gpt4 key购买 nike

我一直在使用来自 http://gmaps-samples-v3.googlecode.com/svn/trunk/infowindow_custom/infowindow-custom.html 的代码,这是目前谷歌关于如何在 Maps API v3 中创建自定义 InfoWindow 的最佳示例。我一直在研究它,到目前为止我已经接近工作了,除了一件事,它是 div 容器,文本内容不会扩展以适应内容,所以它只是掉落而不是扩大气泡。如果我给内容容器一个固定的像素宽度,它可以正常工作,但我无法根据其中的文本量来扩展它。

我已经在这个问题上停留了一段时间。任何帮助将不胜感激!

这是 HTML 页面

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Gayborhood Map Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map_canvas { width: 900px;
height: 400px;
margin: 200px auto 0 auto; }
</style>
<link rel="stylesheet" type="text/css" href="map.css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="InfoBox.js"></script>
<script type="text/javascript">
function initialize() {
var latlng = new google.maps.LatLng(39.947137,-75.161824);
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.HYBRID
};

var gayborhood;

var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);

var gayborhoodcoords = [
new google.maps.LatLng(39.9492017, -75.1631272),
new google.maps.LatLng(39.945423, -75.1639561),
new google.maps.LatLng(39.9450064, -75.160579),
new google.maps.LatLng(39.9487765, -75.1597468),
new google.maps.LatLng(39.9492017, -75.1631272)
];

gayborhood = new google.maps.Polygon({
paths: gayborhoodcoords,
strokeColor: "#00ff00",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#00ff00",
fillOpacity: 0.35
});

gayborhood.setMap(map);

var image = 'red_icon.png';
var myLatLng = new google.maps.LatLng(39.948883,-75.162246);
var redMarker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image
});

var contentString = '<h4>Woody\'s Bar</h4>';

/*var infowindow = new google.maps.InfoWindow({
content: contentString,
disableAutoPan: true
});*/

google.maps.event.addListener(redMarker, 'mouseover', function() {
var infoBox = new InfoBox({marker: redMarker, map: map});
});
/*google.maps.event.addListener(redMarker, 'mouseout', function() {
infowindow.close();
});*/
}

</script>
</head>
<body onload="initialize()">
<div id="map_canvas"></div>
</body>
</html>

这是 InfoBox.js:

    /* 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.marker_ = opts.marker
this.latlng_ = opts.marker.getPosition();
this.map_ = opts.map;
this.offsetVertical_ = -65;
this.offsetHorizontal_ = -20;
this.height_ = 50;
//this.width_ = 159;

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.className = "infobox";
//div.style.width = this.width_ + "px";
//div.style.height = this.height_ + "px";
var leftDiv = document.createElement("div");
leftDiv.className = "bubbleLeftDiv";
var containerDiv = document.createElement("div");
containerDiv.className = "infoboxContainer";
var contentDiv = document.createElement("div");
contentDiv.className = "infoboxContent";

var title = "Much longer title than woody's"

//var infoboxWidth = ( title.length*10 - (title.length) - 40) + "px"
//containerDiv.style.width = infoboxWidth;
//this.width_ = infoboxWidth + 47;
contentDiv.innerHTML = "<h3>" + title + "</h3>";
var rightDiv = document.createElement("div");
rightDiv.className = "bubbleRightDiv";

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

google.maps.event.addListener(this.marker_, 'mouseout', removeInfoBox(this));

div.appendChild(leftDiv)
div.appendChild(containerDiv);
containerDiv.appendChild(contentDiv);
div.appendChild(rightDiv);
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() {
// if we go beyond map, pan map
var map = this.map_;
var bounds = map.getBounds();
if (!bounds) return;

// The position of the infowindow
var position = this.latlng_;

// The dimension of the infowindow
var iwWidth = this.width_;
var iwHeight = this.height_;

// The offset position of the infowindow
var iwOffsetX = this.offsetHorizontal_;
var iwOffsetY = this.offsetVertical_;

// Padding on the infowindow
var padX = 40;
var padY = 40;

// The degrees per pixel
var mapDiv = map.getDiv();
var mapWidth = mapDiv.offsetWidth;
var mapHeight = mapDiv.offsetHeight;
var boundsSpan = bounds.toSpan();
var longSpan = boundsSpan.lng();
var latSpan = boundsSpan.lat();
var degPixelX = longSpan / mapWidth;
var degPixelY = latSpan / mapHeight;

// The bounds of the map
var mapWestLng = bounds.getSouthWest().lng();
var mapEastLng = bounds.getNorthEast().lng();
var mapNorthLat = bounds.getNorthEast().lat();
var mapSouthLat = bounds.getSouthWest().lat();

// The bounds of the infowindow
var iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
var iwEastLng = position.lng() + (iwOffsetX + iwWidth + padX) * degPixelX;
var iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
var iwSouthLat = position.lat() - (iwOffsetY + iwHeight + padY) * degPixelY;

// calculate center shift
var shiftLng =
(iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) +
(iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
var shiftLat =
(iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) +
(iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);

// The center of the map
var center = map.getCenter();

// The new map center
var centerX = center.lng() - shiftLng;
var centerY = center.lat() - shiftLat;

// center the map to the new shifted center
map.setCenter(new google.maps.LatLng(centerY, centerX));

// Remove the listener after panning is complete.
google.maps.event.removeListener(this.boundsChangedListener_);
this.boundsChangedListener_ = null;
};

这是 CSS:

    .infobox {
border: 0px none;
position: absolute;
width: auto;
height: auto;
}

.infoboxContent {
font-family: arial, helvetica, sans-serif;
font-size: 15px;
padding: 0px;
margin: 9px 0px 0px -24px;
position: absolute;
z-index: 105;
}

.infoboxContainer {
background: url('infowindow_bg.png') repeat-x;
height: 50px;
margin-left: 47px;
}

.bubbleLeftDiv {
width: 47px;
height: 50px;
background: url('infowindow_left.png') no-repeat;
position: absolute;
z-index: 102;
}

.bubbleRightDiv {
width: 26px;
height: 50px;
background: url('infowindow_right.png') no-repeat;
position: absolute;
right: -26px;
top: 0px;
}

.clear { clear: both; }

谢谢!!

最佳答案

我遇到了同样的问题。对我有用的方法是动态确定内容的尺寸并正确设置信息框的高度和宽度。我遇到的问题是,在将内容插入 DOM 之前,它没有(正确的)维度值。因此,我的方法如下:

  1. 创建需要插入的DOM内容元素
  2. 将其放入临时容器中
  3. 获取临时容器的尺寸
  4. 删除临时容器
  5. 在 InfoBox 中插入内容并根据临时容器尺寸设置其高度和宽度

这是一个使用 jQuery 框架完成的示例:

    var temp = $("<div class='temp'></div>").html(content).hide().appendTo("body");
var dimentions = {
width : temp.outerWidth(true),
height : temp.outerHeight(true)
};
temp.remove();

var overlayProjection = this.getProjection();
var top_left = overlayProjection.fromLatLngToDivPixel(this.point_);

var dimensions= $.extend({}, dimensions, {
y : top_left.y - dimensions.height,
x : top_left.x - dimensions.width/2
});

var div = this.div_;
$(div).css({
"top": dimensions.y + 'px',
"left" : dimensions.x + 'px',
"width" : dimensions.width + 'px',
"height" : dimensions.height + 'px'
}).html(content);

希望对您有所帮助!

关于javascript - CSS 谷歌地图自定义信息窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5891875/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com