在Google地图中创建自定义信息窗口 [英] Creating custom info windows in Google Maps

查看:108
本文介绍了在Google地图中创建自定义信息窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为Google地图信息窗口(直线边框和透明度等)创建自定义外观。我知道这只适用于外部插件,但我不确定使用哪一个。



我尝试过使用extInfoWindow,但是在使它正常工作时遇到问题。



I也看了PD标记窗口( http://www.pixeldevelopment.com/pdmarker.asp),但它似乎已经更新了一段时间(2007年)

b

谢谢,

解决方案

我自己也有这个问题。
我一直在使用API​​ v.3,并没有真正的定制信息框,所以我自己编写了一个(基于我发现的一些)。
我希望它有帮助: - )



以下是插件代码:

 函数InfoBox(opt_opts){
opt_opts = opt_opts || {};
this.imgPath ='img / infoBox /';
google.maps.OverlayView.apply(this,arguments);
//标准选项(与google.maps.InfoWindow相同):
this.content_ = opt_opts.content || ;
this.maxWidth_ = opt_opts.maxWidth || 0;
this.pixelOffset_ = opt_opts.pixelOffset ||新的google.maps.Size(0,0);
this.position_ = opt_opts.position || new google.maps.LatLng(0,0);
this.zIndex_ = opt_opts.zIndex ||空值;

//附加选项(InfoBox特有):
this.boxStyle_ = opt_opts || {};
this.infoBoxClearance_ = new google.maps.Size(1,1);
this.isHidden_​​ = opt_opts.isHidden ||假;
this.pane_ =overlayMouseTarget;
this.enableEventPropagation_ = opt_opts.enableEventPropagation ||假;
this.div_ = null;
this.closeListener_ = null;
this.eventListener1_ = null;
this.eventListener2_ = null;
this.eventListener3_ = null;
this.contextListener_ = null;
this.fixedWidthSet_ = null;
}

/ * InfoBox在Google Maps API v3中扩展了OverlayView。 * /
InfoBox.prototype = new google.maps.OverlayView();

//创建表示InfoBox的DIV。 @private
InfoBox.prototype.createInfoBoxDiv_ = function(){
var bw,me = this;

//此处理函数可以防止InfoBox中的事件传递给地图。
var cancelHandler = function(e){e.cancelBubble = true;如果(e.stopPagagation)e.stopPropagation(); };
//此处理程序忽略InfoBox中的当前事件,并有条件地阻止事件传递到地图上。它用于contextmenu事件。
var ignoreHandler = function(e){e.returnValue = false; if(e.preventDefault)e.preventDefault(); if(!me.enableEventPropagation _){e.cancelBubble = true;如果(e.stopPagagation)e.stopPropagation(); }};

if(!this.div _){//第一次创建
this.div_ = document.createElement(div);
this.div_.className ='infowindow';
this.setBoxStyle_();

//应用所需样式:
if(this.zIndex_!== null)this.div_.style.zIndex = this.zIndex_;

this.div_.contentDiv = document.createElement('div');
this.div_.contentDiv.className ='infowindow-wrapper';
this.div_.contentDiv.innerHTML = this.content_;
this.div_.innerHTML ='< img src ='+ this.imgPath +'close.pngalign =rightclass =infowindow-close>';
this.div_.appendChild(this.div_.contentDiv);

//将InfoBox DIV添加到DOM
this.getPanes()[this.pane _]。appendChild(this.div_);
this.addClickHandler_();
if(this.div_.style.width)this.fixedWidthSet_ = true;
else {
if(this.maxWidth_!== 0& this.div_.offsetWidth> this.maxWidth_){
this.div_.style.width = this.maxWidth_ ;
this.fixedWidthSet_ = true;
}
else {//需要以下代码来解决MSIE
的问题bw = this.getBoxWidths_();
this.div_.style.width =(this.div_.offsetWidth - bw.left - bw.right)+px;
this.fixedWidthSet_ = false;
}
}

//添加阴影
this.shadowContainer_ = document.createElement(div);
this.shadowContainer_.style.position ='absolute';
this.shadowContainer_.style.display ='block';
this.shadowContainer_.style.zIndex =' - 99';
this.getPanes()['overlayShadow']。appendChild(this.shadowContainer_);

this.shadow = document.createElement('img');
this.shadow.src = this.imgPath +'shadow.png';
this.shadow.style.position ='绝对';
this.shadow.style.width ='100%';
this.shadow.style.height ='100%';

this.shadowContainer_.appendChild(this.shadow);
if(!this.enableEventPropagation_){
this.eventListener1_ = google.maps.event.addDomListener(this.div_.contentDiv,mousedown,cancelHandler);
this.eventListener2_ = google.maps.event.addDomListener(this.div_,click,function(e){
e.cancelBubble = true; if(e.stopPropagation)e.stopPropagation() ;
if(GoogleMap&& GoogleMap.closeEditors)GoogleMap.closeEditors(true);
});
//this.eventListener3_ = google.maps.event.addDomListener(this.div_,dblclick,cancelHandler);
try {this.eventListener3_ = google.maps.event.addDomListener(this.div_,dblclick,facilityEditor);} catch(e){}
}
this.contextListener_ = google .maps.event.addDomListener(this.div_,contextmenu,ignoreHandler);

var contentWidth = parseInt(this.div_.style.width.slice(0,-2)),contentHeight = this.div_.offsetHeight;
this.wrapperParts = {//创建一个引用每张图片的对象
tl:{l:-26,t:-26,w:26,h:26},
t:{ l:0,t:-26,w:contentWidth,h:26},
tr:{l:contentWidth,t:-26,w:26,h:26},
l:{l :-26,t:0,w:26,h:contentHeight},
r:{l:contentWidth,t:0,w:26,h:contentHeight},
bl:{l: - 26,t:contentHeight,w:26,h:26},
b:{l:0,t:contentHeight,w:contentWidth,h:26},
br:{l:contentWidth,t :contentHeight,w:26,h:26},
p:{l:contentWidth-170,t:contentHeight + 18,w:92,h:77}
}
for在this.wrapperParts){//创建图像DOM对象
var img = document.createElement('img');
img.src = this.imgPath + i +'.png'; //根据wrapperParts对象的属性名称从本地图像目录加载图像
img.style.position ='absolute'; //设置合适的定位属性
img.style.top = this.wrapperParts [i] .t +'px';
img.style.left = this.wrapperParts [i] .l +'px';
img.style.width = this.wrapperParts [i] .w +'px';
img.style.height = this.wrapperParts [i] .h +'px';
this.div_.appendChild(img);
this.wrapperParts [i] .img = img;
}
google.maps.event.trigger(this,domready);
}

else {
var contentWidth = parseInt(this.div_.style.width.slice(0,-2)),contentHeight = this.div_.offsetHeight,twp = this.wrapperParts;
twp.t.img.style.width = contentWidth +'px';
twp.tr.img.style.left = contentWidth +'px';
twp.l.img.style.height = contentHeight +'px';
twp.r.img.style.left = contentWidth +'px';
twp.r.img.style.height = contentHeight +'px';
twp.bl.img.style.top = contentHeight +'px';
twp.b.img.style.top = contentHeight +'px';
twp.b.img.style.width = contentWidth +'px';
twp.br.img.style.left = contentWidth +'px';
twp.br.img.style.top = contentHeight +'px';
twp.p.img.style.left =(contentWidth-170)+'px';
twp.p.img.style.top =(contentHeight + 18)+'px';
}
};

InfoBox.prototype.addClickHandler_ = function(){
this.closeListener_ = google.maps.event.addDomListener(this.div_.firstChild,'click',this.getCloseClickHandler_()) ;
try {this.eventListener3_ = google.maps.event.addDomListener(this.div_,dblclick,facilityEditor);} catch(e){}
};
InfoBox.prototype.getCloseClickHandler_ = function(){var me = this;返回函数(){me.close(); google.maps.event.trigger(我,closeclick); }; };

//播放地图,以便InfoBox完全显示在地图的可见区域内。 @private
InfoBox.prototype.panBox_ = function(disablePan){
if(!disablePan){
var map = this.getMap();
var bounds = map.getBounds();
//每像素的度数
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;

//地图边界
var mapWestLng = bounds.getSouthWest()。lng();
var mapEastLng = bounds.getNorthEast()。lng();
var mapNorthLat = bounds.getNorthEast()。lat();
var mapSouthLat = bounds.getSouthWest()。lat();

//框的边界
var position = this.position_;
var iwOffsetX = this.pixelOffset_.width;
var iwOffsetY = this.pixelOffset_.height;
var padX = this.infoBoxClearance_.width;
var padY = this.infoBoxClearance_.height;

var iwWestLng = position.lng()+(iwOffsetX - padX - this.div_.contentDiv.offsetWidth / 2 - 450)* degPixelX; // 450 - 右移 - 从边栏下方
var iwEastLng = position.lng()+(iwOffsetX + padX + 220)* degPixelX;
var iwNorthLat = position.lat() - (iwOffsetY - padY - this.div_.contentDiv.offsetHeight - 180)* degPixelY; // 180 - 向下移动 - 从顶部搜索栏下方
var iwSouthLat = position.lat() - (iwOffsetY + padY + 20)* degPixelY;

//计算中心偏移
var shiftLng =(iwWestLng mapEastLng?mapEastLng - iwEastLng:0);
var shiftLat =(iwNorthLat> mapNorthLat?mapNorthLat - iwNorthLat:0)+(iwSouthLat< mapSouthLat?mapSouthLat - iwSouthLat:0);
if(!(shiftLat === 0&& shiftLng === 0)){
//将地图移动到新移动的中心。
var c = map.getCenter();
map.setCenter(new google.maps.LatLng(c.lat() - shiftLat,c.lng() - shiftLng));
}
}
};

//设置信息框的样式。 @private
InfoBox.prototype.setBoxStyle_ = function(){
var i;
var boxStyle = this.boxStyle_;
for(i in boxStyle)if(boxStyle.hasOwnProperty(i))this.div_.style [i] = boxStyle [i];
//为MSIE的好处修正不透明风格:
if(typeof this.div_.style.opacity!==undefined)this.div_.style.filter =alpha(opacity = +(this.div_.style.opacity * 100)+);
};

//获取InfoBox边框的宽度。 @私人的; @return {Object} widths object(top,bottom left,right)
InfoBox.prototype.getBoxWidths_ = function(){
var computedStyle;
var bw = {top:0,bottom:0,left:0,right:0};
var box = this.div_;
if(document.defaultView&&document.defaultView.getComputedStyle){
computedStyle = box.ownerDocument.defaultView.getComputedStyle(box,);
if(computedStyle){
//计算的样式总是以像素为单位(好!)
bw.top = parseInt(computedStyle.borderTopWidth,10)|| 0;
bw.bottom = parseInt(computedStyle.borderBottomWidth,10)|| 0;
bw.left = parseInt(computedStyle.borderLeftWidth,10)|| 0;
bw.right = parseInt(computedStyle.borderRightWidth,10)|| 0;


else if(document.documentElement.currentStyle){// MSIE
if(box.currentStyle){
//当前样式可能不是以像素为单位,但假设它们是(坏!)
bw.top = parseInt(box.currentStyle.borderTopWidth,10)|| 0;
bw.bottom = parseInt(box.currentStyle.borderBottomWidth,10)|| 0;
bw.left = parseInt(box.currentStyle.borderLeftWidth,10)|| 0;
bw.right = parseInt(box.currentStyle.borderRightWidth,10)|| 0;
}
}
return bw;
};

//当< tt>关闭时调用< / tt>叫做。不要直接调用它。
InfoBox.prototype.onRemove = function(){
if(this.div_){
this.shadowContainer_.parentNode.removeChild(this.shadowContainer_);
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
};

//根据当前地图投影和缩放级别绘制InfoBox。
InfoBox.prototype.draw = function(){
this.createInfoBoxDiv_();
var pixPosition = this.getProjection()。fromLatLngToDivPixel(this.position_);

this.div_.style.left =(pixPosition.x - this.div_.offsetWidth + 180)+px;
this.div_.style.top =(pixPosition.y - this.div_.offsetHeight - 125)+px;

this.shadowContainer_.style.left =(pixPosition.x - this.div_.offsetWidth + 220)+'px';
this.shadowContainer_.style.top =(pixPosition.y - this.div_.offsetHeight - 130)+px;

this.shadowContainer_.style.height =(this.div_.offsetHeight + 100)+'px';
this.shadowContainer_.style.width =(this.div_.offsetWidth + 100)+'px';

if(this.isHidden_​​)this.div_.style.visibility ='hidden';
else this.div_.style.visibility =visible;

this.panBox_();
};


InfoBox.prototype.setContent = function(content){
this.content_ = content;
if(this.div _){//使事情与MSIE协同工作所需的奇数代码。
this.div_.style.visibility ='hidden'
if(!this.fixedWidthSet_)this.div_.style.width =;
this.div_.contentDiv.innerHTML = content;
//使事情与MSIE协同工作所需的不良代码。 (确保关闭框实际上向右浮动。)
if(!this.fixedWidthSet _){this.div_.style.width = this.div_.offsetWidth +px; this.div_.contentDiv.innerHTML = content; }
this.addClickHandler_();
}
//当InfoBox的内容发生变化时,将触发此事件。 @name InfoBox#content_changed; @event
google.maps.event.trigger(this,content_changed);
};

//设置InfoBox的地理位置。 @param {LatLng} latlng
InfoBox.prototype.setPosition = function(latlng){
this.position_ = latlng;
if(this.div_)this.draw();
//当InfoBox的位置发生变化时,将触发此事件。 @name InfoBox#position_changed; @event
google.maps.event.trigger(this,position_changed);
};


InfoBox.prototype.getContent = function(){return this.content_; }; //返回InfoBox的内容。 @returns {string}
InfoBox.prototype.show = function(){this.isHidden_​​ = false; this.div_.style.visibility =visible; }; //显示信息框。
InfoBox.prototype.hide = function(){this.isHidden_​​ = true; this.div_.style.visibility =隐藏; }; //隐藏信息框。

InfoBox.prototype.open = function(map,anchor){
if(anchor)this.position_ = anchor.getPosition();
this.setMap(map);
};

//从地图中删除InfoBox。
InfoBox.prototype.close = function(){
if(this.closeListener_){
google.maps.event.removeListener(this.closeListener_);
this.closeListener_ = null;
}
if(this.contextListener_){
google.maps.event.removeListener(this.contextListener_);
this.contextListener_ = null;
}

this.setMap(null);
};

以下是示例用法:

  infobox = new InfoBox({width:260px}); //初始化
infobox.setContent('Loading ...'); //设置内容
infobox.open(googlemap,marker); //在标记
上打开infobox.draw(); //如果信息框大小发生变化,则重新绘制
infobox.close();

以下是网站的使用地点: http://goo.gl/A8g1D


I need to create a custom look for the Google Maps info windows (straight-edge frame and transparency, etc). I understand this is only doable with an external plugin, but I am not sure which one to use.

I have tried to use extInfoWindow, but I have had problems with getting it to work properly.

I have also looked at PD Marker window (http://www.pixeldevelopment.com/pdmarker.asp), but it seems it has been a while since it has been updated (2007)

Are there any other plugins with similar functionality?

Thank you,

解决方案

I had that problem myself. I've been using api v.3 and there was no really good custom infobox out there, so I made up one myself (based on a few that I've found). I hope it helps :-)

Here's the plugin code:

function InfoBox(opt_opts) {
    opt_opts = opt_opts || {};
    this.imgPath='img/infoBox/';
    google.maps.OverlayView.apply(this, arguments);
    // Standard options (in common with google.maps.InfoWindow):
    this.content_ = opt_opts.content || "";
    this.maxWidth_ = opt_opts.maxWidth || 0;
    this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0);
    this.position_ = opt_opts.position || new google.maps.LatLng(0, 0);
    this.zIndex_ = opt_opts.zIndex || null;

    // Additional options (unique to InfoBox):
    this.boxStyle_ = opt_opts || {};
    this.infoBoxClearance_ = new google.maps.Size(1, 1);
    this.isHidden_ = opt_opts.isHidden || false;
    this.pane_ = "overlayMouseTarget";
    this.enableEventPropagation_ = opt_opts.enableEventPropagation || false;
    this.div_ = null;
    this.closeListener_ = null;
    this.eventListener1_ = null;
    this.eventListener2_ = null;
    this.eventListener3_ = null;
    this.contextListener_ = null;
    this.fixedWidthSet_ = null;
}

/* InfoBox extends OverlayView in the Google Maps API v3. */
InfoBox.prototype = new google.maps.OverlayView();

// Creates the DIV representing the InfoBox. @private
InfoBox.prototype.createInfoBoxDiv_ = function(){
    var bw, me = this;

    // This handler prevents an event in the InfoBox from being passed on to the map.
    var cancelHandler = function (e){ e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); };
    // This handler ignores the current event in the InfoBox and conditionally prevents the event from being passed on to the map. It is used for the contextmenu event.
    var ignoreHandler = function (e) { e.returnValue = false; if (e.preventDefault) e.preventDefault(); if (!me.enableEventPropagation_){ e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } };

    if (!this.div_){    // first time create
        this.div_ = document.createElement("div");
        this.div_.className = 'infowindow';
        this.setBoxStyle_();

        // Apply required styles:
        if (this.zIndex_ !== null) this.div_.style.zIndex = this.zIndex_;

        this.div_.contentDiv = document.createElement('div');
        this.div_.contentDiv.className = 'infowindow-wrapper';
        this.div_.contentDiv.innerHTML = this.content_;
        this.div_.innerHTML = '<img src="'+this.imgPath+'close.png" align="right" class="infowindow-close">';
        this.div_.appendChild(this.div_.contentDiv);

        // Add the InfoBox DIV to the DOM
        this.getPanes()[this.pane_].appendChild(this.div_);
        this.addClickHandler_();
        if (this.div_.style.width) this.fixedWidthSet_ = true;
        else {
            if (this.maxWidth_ !== 0 && this.div_.offsetWidth > this.maxWidth_) {
                this.div_.style.width = this.maxWidth_;
                this.fixedWidthSet_ = true;
            } 
            else { // The following code is needed to overcome problems with MSIE
                bw = this.getBoxWidths_();
                this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px";
                this.fixedWidthSet_ = false;
            }
        }

        //add shadow
        this.shadowContainer_ = document.createElement("div");
        this.shadowContainer_.style.position='absolute';
        this.shadowContainer_.style.display = 'block';
        this.shadowContainer_.style.zIndex='-99';
        this.getPanes()['overlayShadow'].appendChild(this.shadowContainer_);

        this.shadow = document.createElement('img');
        this.shadow.src = this.imgPath+'shadow.png';
        this.shadow.style.position='absolute';
        this.shadow.style.width = '100%';
        this.shadow.style.height    = '100%';

        this.shadowContainer_.appendChild(this.shadow);
        if (!this.enableEventPropagation_) {
            this.eventListener1_ = google.maps.event.addDomListener(this.div_.contentDiv, "mousedown", cancelHandler);
            this.eventListener2_ = google.maps.event.addDomListener(this.div_, "click", function(e){
                e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
                if (GoogleMap && GoogleMap.closeEditors) GoogleMap.closeEditors(true);              
            });
            //this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", cancelHandler);
            try{ this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", facilityEditor);}catch(e){}
        }
        this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler);

        var contentWidth = parseInt(this.div_.style.width.slice(0,-2)), contentHeight = this.div_.offsetHeight;
        this.wrapperParts = { //create an object to reference each image
            tl:{l:-26, t:-26, w:26, h:26},
            t:{l:0, t:-26, w:contentWidth, h:26},
            tr:{l:contentWidth, t:-26, w:26, h:26},
            l:{l:-26, t:0, w:26, h:contentHeight},
            r:{l:contentWidth, t:0, w:26, h: contentHeight },
            bl:{l:-26, t:contentHeight, w:26, h:26},
            b:{l:0, t:contentHeight, w:contentWidth, h:26},
            br:{l:contentWidth, t:contentHeight, w:26, h:26},
            p:{l:contentWidth-170, t:contentHeight+18, w:92, h:77 }
        }
        for (i in this.wrapperParts){ //create the image DOM objects
            var img = document.createElement('img');
            img.src = this.imgPath + i + '.png'; //load the image from your local image directory based on the property name of the wrapperParts object
            img.style.position='absolute'; //set the appropriate positioning attributes
            img.style.top=this.wrapperParts[i].t+'px';
            img.style.left=this.wrapperParts[i].l+'px';
            img.style.width=this.wrapperParts[i].w+'px';
            img.style.height=this.wrapperParts[i].h+'px';
            this.div_.appendChild(img);
            this.wrapperParts[i].img = img;
        }
        google.maps.event.trigger(this, "domready");
    }

    else {
        var contentWidth = parseInt(this.div_.style.width.slice(0,-2)), contentHeight = this.div_.offsetHeight, twp=this.wrapperParts;
        twp.t.img.style.width=contentWidth+'px';
        twp.tr.img.style.left=contentWidth+'px';
        twp.l.img.style.height=contentHeight+'px';
        twp.r.img.style.left=contentWidth+'px';
        twp.r.img.style.height=contentHeight+'px';
        twp.bl.img.style.top=contentHeight+'px';
        twp.b.img.style.top=contentHeight+'px';
        twp.b.img.style.width=contentWidth+'px';
        twp.br.img.style.left=contentWidth+'px';
        twp.br.img.style.top=contentHeight+'px';
        twp.p.img.style.left=(contentWidth-170)+'px';
        twp.p.img.style.top=(contentHeight+18)+'px';
    }
};

InfoBox.prototype.addClickHandler_=function(){ 
    this.closeListener_ = google.maps.event.addDomListener(this.div_.firstChild, 'click', this.getCloseClickHandler_());
    try{ this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", facilityEditor);}catch(e){}
};
InfoBox.prototype.getCloseClickHandler_=function () { var me = this; return function(){ me.close(); google.maps.event.trigger(me, "closeclick"); }; };

//Pans the map so that the InfoBox appears entirely within the map's visible area. @private
InfoBox.prototype.panBox_ = function (disablePan) {
  if (!disablePan) {
    var map = this.getMap();
    var bounds = map.getBounds();
    // 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 box
    var position = this.position_;
    var iwOffsetX = this.pixelOffset_.width;
    var iwOffsetY = this.pixelOffset_.height;
    var padX = this.infoBoxClearance_.width;
    var padY = this.infoBoxClearance_.height;

    var iwWestLng = position.lng() + (iwOffsetX - padX - this.div_.contentDiv.offsetWidth/2 - 450) * degPixelX; // 450 - move right - from under the sidebar
    var iwEastLng = position.lng() + (iwOffsetX + padX + 220) * degPixelX;
    var iwNorthLat = position.lat() - (iwOffsetY - padY - this.div_.contentDiv.offsetHeight - 180) * degPixelY; // 180 - move down - from under the top search bar
    var iwSouthLat = position.lat() - (iwOffsetY + padY + 20) * 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);
    if (!(shiftLat === 0 && shiftLng === 0)) {
      // Move the map to the new shifted center.
      var c = map.getCenter();
      map.setCenter(new google.maps.LatLng(c.lat() - shiftLat, c.lng() - shiftLng));
    }
  }
};

// Sets the style of the InfoBox. @private
 InfoBox.prototype.setBoxStyle_ = function () {
  var i;
  var boxStyle = this.boxStyle_;
  for (i in boxStyle)  if (boxStyle.hasOwnProperty(i))  this.div_.style[i] = boxStyle[i];
  // Fix up opacity style for benefit of MSIE:
  if (typeof this.div_.style.opacity !== "undefined")  this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")";
};

// Get the widths of the borders of the InfoBox. @private; @return {Object} widths object (top, bottom left, right)
InfoBox.prototype.getBoxWidths_ = function () {
  var computedStyle;
  var bw = {top: 0, bottom: 0, left: 0, right: 0};
  var box = this.div_;
  if (document.defaultView && document.defaultView.getComputedStyle) {
    computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, "");
    if (computedStyle) {
      // The computed styles are always in pixel units (good!)
      bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0;
    }
  } 
  else if (document.documentElement.currentStyle) { // MSIE
    if (box.currentStyle) {
      // The current styles may not be in pixel units, but assume they are (bad!)
      bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0;
    }
  }
  return bw;
};

// Invoked when <tt>close</tt> is called. Do not call it directly.
InfoBox.prototype.onRemove = function () {
  if (this.div_) {
     this.shadowContainer_.parentNode.removeChild(this.shadowContainer_);
    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
  }
};

//Draws the InfoBox based on the current map projection and zoom level.
InfoBox.prototype.draw = function(){
    this.createInfoBoxDiv_();
    var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_);

    this.div_.style.left = (pixPosition.x - this.div_.offsetWidth + 180 ) + "px";
    this.div_.style.top = (pixPosition.y - this.div_.offsetHeight - 125) + "px";

    this.shadowContainer_.style.left = (pixPosition.x - this.div_.offsetWidth + 220 ) + 'px';
    this.shadowContainer_.style.top = (pixPosition.y - this.div_.offsetHeight - 130) + "px";

    this.shadowContainer_.style.height = (this.div_.offsetHeight+100 ) + 'px';
    this.shadowContainer_.style.width = (this.div_.offsetWidth+100 ) + 'px';

    if (this.isHidden_) this.div_.style.visibility = 'hidden';
    else this.div_.style.visibility = "visible";

    this.panBox_();
};


InfoBox.prototype.setContent = function(content){
    this.content_ = content;
    if (this.div_){// Odd code required to make things work with MSIE.
        this.div_.style.visibility='hidden'
        if (!this.fixedWidthSet_) this.div_.style.width = "";
        this.div_.contentDiv.innerHTML = content;
        // Perverse code required to make things work with MSIE. (Ensures the close box does, in fact, float to the right.)
        if (!this.fixedWidthSet_){ this.div_.style.width = this.div_.offsetWidth + "px"; this.div_.contentDiv.innerHTML = content; }
        this.addClickHandler_();
    }
    // This event is fired when the content of the InfoBox changes. @name InfoBox#content_changed; @event
    google.maps.event.trigger(this, "content_changed");
};

//Sets the geographic location of the InfoBox. @param {LatLng} latlng
InfoBox.prototype.setPosition = function (latlng) { 
  this.position_ = latlng;
  if (this.div_) this.draw();
  //This event is fired when the position of the InfoBox changes. @name InfoBox#position_changed;  @event
  google.maps.event.trigger(this, "position_changed");
};


InfoBox.prototype.getContent = function () {  return this.content_; }; //Returns the content of the InfoBox. @returns {string}
InfoBox.prototype.show = function (){ this.isHidden_ = false; this.div_.style.visibility = "visible"; }; //Shows the InfoBox.
InfoBox.prototype.hide = function (){ this.isHidden_ = true; this.div_.style.visibility = "hidden"; }; //Hides the InfoBox.

InfoBox.prototype.open = function (map, anchor) {
    if (anchor) this.position_ = anchor.getPosition();
    this.setMap(map);
};

//Removes the InfoBox from the map.
InfoBox.prototype.close = function (){
  if (this.closeListener_) {
    google.maps.event.removeListener(this.closeListener_);
    this.closeListener_ = null;
  }
  if (this.contextListener_) {
    google.maps.event.removeListener(this.contextListener_);
    this.contextListener_ = null;
  }

  this.setMap(null);
};

and here's the sample usage:

infobox = new InfoBox({ width: "260px" }); // initialize
infobox.setContent('Loading...');  // set content
infobox.open(googlemap, marker);   // open on the marker
infobox.draw(); // to redraw if infobox size changed
infobox.close();

Here's the website, where this is used: http://goo.gl/A8g1D

这篇关于在Google地图中创建自定义信息窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆