Google Map 自定义 infowindow

最近做的东西用到了infowindow,不过google提供的样式太难看了,于是想改变一下样式。看了一下好像infowindow的样式不太好改。

查了半天资料,看到一个infobox,感觉真的挺好用。提供了完整的api,样式的改变也容易。http://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries里面还有其他的插件

都很好用。View example (infobox-basic.html) ,这是他给的一个demo,样式也很简单。但是通过他的api,可以很容易就作出更改了。遇到改infowindow的可以试一下。

 

infobox.js 插件

 

/**

 * @name InfoBox

 * @version 1.1.9 [October 2, 2011]

 * @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google)

 * @copyright Copyright 2010 Gary Little [gary at luxcentral.com]

 * @fileoverview InfoBox extends the Google Maps JavaScript API V3 <tt>OverlayView</tt> class.

 *  <p>

 *  An InfoBox behaves like a <tt>google.maps.InfoWindow</tt>, but it supports several

 *  additional properties for advanced styling. An InfoBox can also be used as a map label.

 *  <p>

 *  An InfoBox also fires the same events as a <tt>google.maps.InfoWindow</tt>.

 *  <p>

 *  Browsers tested:

 *  <p>

 *  Mac -- Safari (4.0.4), Firefox (3.6), Opera (10.10), Chrome (4.0.249.43), OmniWeb (5.10.1)

 *  <br>

 *  Win -- Safari, Firefox, Opera, Chrome (3.0.195.38), Internet Explorer (8.0.6001.18702)

 *  <br>

 *  iPod Touch/iPhone -- Safari (3.1.2)

 */



/*!

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *       http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



/*jslint browser:true */

/*global google */



/**

 * @name InfoBoxOptions

 * @class This class represents the optional parameter passed to the {@link InfoBox} constructor.

 * @property {string|Node} content The content of the InfoBox (plain text or an HTML DOM node).

 * @property {boolean} disableAutoPan Disable auto-pan on <tt>open</tt> (default is <tt>false</tt>).

 * @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum.

 * @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox

 *  (or the bottom left corner if the <code>alignBottom</code> property is <code>true</code>)

 *  to the map pixel corresponding to <tt>position</tt>.

 * @property {LatLng} position The geographic location at which to display the InfoBox.

 * @property {number} zIndex The CSS z-index style value for the InfoBox.

 *  Note: This value overrides a zIndex setting specified in the <tt>boxStyle</tt> property.

 * @property {string} boxClass The name of the CSS class defining the styles for the InfoBox container.

 *  The default name is <code>infoBox</code>.

 * @property {Object} [boxStyle] An object literal whose properties define specific CSS

 *  style values to be applied to the InfoBox. Style values defined here override those that may

 *  be defined in the <code>boxClass</code> style sheet. If this property is changed after the

 *  InfoBox has been created, all previously set styles (except those defined in the style sheet)

 *  are removed from the InfoBox before the new style values are applied.

 * @property {string} closeBoxMargin The CSS margin style value for the close box.

 *  The default is "2px" (a 2-pixel margin on all sides).

 * @property {string} closeBoxURL The URL of the image representing the close box.

 *  Note: The default is the URL for Google's standard close box.

 *  Set this property to "" if no close box is required.

 * @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the

 *  map edge after an auto-pan.

 * @property {boolean} isHidden Hide the InfoBox on <tt>open</tt> (default is <tt>false</tt>).

 * @property {boolean} alignBottom Align the bottom left corner of the InfoBox to the <code>position</code>

 *  location (default is <tt>false</tt> which means that the top left corner of the InfoBox is aligned).

 * @property {string} pane The pane where the InfoBox is to appear (default is "floatPane").

 *  Set the pane to "mapPane" if the InfoBox is being used as a map label.

 *  Valid pane names are the property names for the <tt>google.maps.MapPanes</tt> object.

 * @property {boolean} enableEventPropagation Propagate mousedown, click, dblclick,

 *  and contextmenu events in the InfoBox (default is <tt>false</tt> to mimic the behavior

 *  of a <tt>google.maps.InfoWindow</tt>). Set this property to <tt>true</tt> if the InfoBox

 *  is being used as a map label. iPhone note: This property setting has no effect; events are

 *  always propagated.

 */



/**

 * Creates an InfoBox with the options specified in {@link InfoBoxOptions}.

 *  Call <tt>InfoBox.open</tt> to add the box to the map.

 * @constructor

 * @param {InfoBoxOptions} [opt_opts]

 */

function InfoBox(opt_opts) {



  opt_opts = opt_opts || {};



  google.maps.OverlayView.apply(this, arguments);



  // Standard options (in common with google.maps.InfoWindow):

  //

  this.content_ = opt_opts.content || "";

  this.disableAutoPan_ = opt_opts.disableAutoPan || false;

  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.boxClass_ = opt_opts.boxClass || "infoBox";

  this.boxStyle_ = opt_opts.boxStyle || {};

  this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px";

  this.closeBoxURL_ = opt_opts.closeBoxURL || "http://www.google.com/intl/en_us/mapfiles/close.gif";

  if (opt_opts.closeBoxURL === "") {

    this.closeBoxURL_ = "";

  }

  this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1);

  this.isHidden_ = opt_opts.isHidden || false;

  this.alignBottom_ = opt_opts.alignBottom || false;

  this.pane_ = opt_opts.pane || "floatPane";

  this.enableEventPropagation_ = opt_opts.enableEventPropagation || false;



  this.div_ = null;

  this.closeListener_ = null;

  this.eventListener1_ = null;

  this.eventListener2_ = null;

  this.eventListener3_ = null;

  this.moveListener_ = 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;

  var 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_) {



      cancelHandler(e);

    }

  };



  if (!this.div_) {



    this.div_ = document.createElement("div");



    this.setBoxStyle_();



    if (typeof this.content_.nodeType === "undefined") {

      this.div_.innerHTML = this.getCloseBoxImg_() + this.content_;

    } else {

      this.div_.innerHTML = this.getCloseBoxImg_();

      this.div_.appendChild(this.content_);

    }



    // 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.div_.style.overflow = "auto";

        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;

      }

    }



    this.panBox_(this.disableAutoPan_);



    if (!this.enableEventPropagation_) {



      // Cancel event propagation.

      //

      this.eventListener1_ = google.maps.event.addDomListener(this.div_, "mousedown", cancelHandler);

      this.eventListener2_ = google.maps.event.addDomListener(this.div_, "click", cancelHandler);

      this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", cancelHandler);

      this.eventListener4_ = google.maps.event.addDomListener(this.div_, "mouseover", function (e) {

        this.style.cursor = "default";

      });

    }



    this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler);



    /**

     * This event is fired when the DIV containing the InfoBox's content is attached to the DOM.

     * @name InfoBox#domready

     * @event

     */

    google.maps.event.trigger(this, "domready");

  }

};



/**

 * Returns the HTML <IMG> tag for the close box.

 * @private

 */

InfoBox.prototype.getCloseBoxImg_ = function () {



  var img = "";



  if (this.closeBoxURL_ !== "") {



    img  = "<img";

    img += " src='" + this.closeBoxURL_ + "'";

    img += " align=right"; // Do this because Opera chokes on style='float: right;'

    img += " style='";

    img += " position: relative;"; // Required by MSIE

    img += " cursor: pointer;";

    img += " margin: " + this.closeBoxMargin_ + ";";

    img += "'>";

  }



  return img;

};



/**

 * Adds the click handler to the InfoBox close box.

 * @private

 */

InfoBox.prototype.addClickHandler_ = function () {



  var closeBox;



  if (this.closeBoxURL_ !== "") {



    closeBox = this.div_.firstChild;

    this.closeListener_ = google.maps.event.addDomListener(closeBox, 'click', this.getCloseClickHandler_());



  } else {



    this.closeListener_ = null;

  }

};



/**

 * Returns the function to call when the user clicks the close box of an InfoBox.

 * @private

 */

InfoBox.prototype.getCloseClickHandler_ = function () {



  var me = this;



  return function (e) {



    // 1.0.3 fix: Always prevent propagation of a close box click to the map:

    e.cancelBubble = true;



    if (e.stopPropagation) {



      e.stopPropagation();

    }



    me.close();



    /**

     * This event is fired when the InfoBox's close box is clicked.

     * @name InfoBox#closeclick

     * @event

     */

    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) {



  var map;

  var bounds;

  var xOffset = 0, yOffset = 0;



  if (!disablePan) {



    map = this.getMap();



    if (map instanceof google.maps.Map) { // Only pan if attached to map, not panorama



      if (!map.getBounds().contains(this.position_)) {

      // Marker not in visible area of map, so set center

      // of map to the marker position first.

        map.setCenter(this.position_);

      }



      bounds = map.getBounds();



      var mapDiv = map.getDiv();

      var mapWidth = mapDiv.offsetWidth;

      var mapHeight = mapDiv.offsetHeight;

      var iwOffsetX = this.pixelOffset_.width;

      var iwOffsetY = this.pixelOffset_.height;

      var iwWidth = this.div_.offsetWidth;

      var iwHeight = this.div_.offsetHeight;

      var padX = this.infoBoxClearance_.width;

      var padY = this.infoBoxClearance_.height;

      var pixPosition = this.getProjection().fromLatLngToContainerPixel(this.position_);



      if (pixPosition.x < (-iwOffsetX + padX)) {

        xOffset = pixPosition.x + iwOffsetX - padX;

      } else if ((pixPosition.x + iwWidth + iwOffsetX + padX) > mapWidth) {

        xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth;

      }

      if (this.alignBottom_) {

        if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) {

          yOffset = pixPosition.y + iwOffsetY - padY - iwHeight;

        } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) {

          yOffset = pixPosition.y + iwOffsetY + padY - mapHeight;

        }

      } else {

        if (pixPosition.y < (-iwOffsetY + padY)) {

          yOffset = pixPosition.y + iwOffsetY - padY;

        } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) {

          yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight;

        }

      }



      if (!(xOffset === 0 && yOffset === 0)) {



        // Move the map to the shifted center.

        //

        var c = map.getCenter();

        map.panBy(xOffset, yOffset);

      }

    }

  }

};



/**

 * Sets the style of the InfoBox by setting the style sheet and applying

 * other specific styles requested.

 * @private

 */

InfoBox.prototype.setBoxStyle_ = function () {



  var i, boxStyle;



  if (this.div_) {



    // Apply style values from the style sheet defined in the boxClass parameter:

    this.div_.className = this.boxClass_;



    // Clear existing inline style values:

    this.div_.style.cssText = "";



    // Apply style values defined in the boxStyle parameter:

    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.opacity !== "") {



      this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")";

    }



    // Apply required styles:

    //

    this.div_.style.position = "absolute";

    this.div_.style.visibility = 'hidden';

    if (this.zIndex_ !== null) {



      this.div_.style.zIndex = this.zIndex_;

    }

  }

};



/**

 * 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.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.pixelOffset_.width) + "px";

  

  if (this.alignBottom_) {

    this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px";

  } else {

    this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px";

  }



  if (this.isHidden_) {



    this.div_.style.visibility = 'hidden';



  } else {



    this.div_.style.visibility = "visible";

  }

};



/**

 * Sets the options for the InfoBox. Note that changes to the <tt>maxWidth</tt>,

 *  <tt>closeBoxMargin</tt>, <tt>closeBoxURL</tt>, and <tt>enableEventPropagation</tt>

 *  properties have no affect until the current InfoBox is <tt>close</tt>d and a new one

 *  is <tt>open</tt>ed.

 * @param {InfoBoxOptions} opt_opts

 */

InfoBox.prototype.setOptions = function (opt_opts) {

  if (typeof opt_opts.boxClass !== "undefined") { // Must be first



    this.boxClass_ = opt_opts.boxClass;

    this.setBoxStyle_();

  }

  if (typeof opt_opts.boxStyle !== "undefined") { // Must be second



    this.boxStyle_ = opt_opts.boxStyle;

    this.setBoxStyle_();

  }

  if (typeof opt_opts.content !== "undefined") {



    this.setContent(opt_opts.content);

  }

  if (typeof opt_opts.disableAutoPan !== "undefined") {



    this.disableAutoPan_ = opt_opts.disableAutoPan;

  }

  if (typeof opt_opts.maxWidth !== "undefined") {



    this.maxWidth_ = opt_opts.maxWidth;

  }

  if (typeof opt_opts.pixelOffset !== "undefined") {



    this.pixelOffset_ = opt_opts.pixelOffset;

  }

  if (typeof opt_opts.alignBottom !== "undefined") {



    this.alignBottom_ = opt_opts.alignBottom;

  }

  if (typeof opt_opts.position !== "undefined") {



    this.setPosition(opt_opts.position);

  }

  if (typeof opt_opts.zIndex !== "undefined") {



    this.setZIndex(opt_opts.zIndex);

  }

  if (typeof opt_opts.closeBoxMargin !== "undefined") {



    this.closeBoxMargin_ = opt_opts.closeBoxMargin;

  }

  if (typeof opt_opts.closeBoxURL !== "undefined") {



    this.closeBoxURL_ = opt_opts.closeBoxURL;

  }

  if (typeof opt_opts.infoBoxClearance !== "undefined") {



    this.infoBoxClearance_ = opt_opts.infoBoxClearance;

  }

  if (typeof opt_opts.isHidden !== "undefined") {



    this.isHidden_ = opt_opts.isHidden;

  }

  if (typeof opt_opts.enableEventPropagation !== "undefined") {



    this.enableEventPropagation_ = opt_opts.enableEventPropagation;

  }



  if (this.div_) {



    this.draw();

  }

};



/**

 * Sets the content of the InfoBox.

 *  The content can be plain text or an HTML DOM node.

 * @param {string|Node} content

 */

InfoBox.prototype.setContent = function (content) {

  this.content_ = content;



  if (this.div_) {



    if (this.closeListener_) {



      google.maps.event.removeListener(this.closeListener_);

      this.closeListener_ = null;

    }



    // Odd code required to make things work with MSIE.

    //

    if (!this.fixedWidthSet_) {



      this.div_.style.width = "";

    }



    if (typeof content.nodeType === "undefined") {

      this.div_.innerHTML = this.getCloseBoxImg_() + content;

    } else {

      this.div_.innerHTML = this.getCloseBoxImg_();

      this.div_.appendChild(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";

      if (typeof content.nodeType === "undefined") {

        this.div_.innerHTML = this.getCloseBoxImg_() + content;

      } else {

        this.div_.innerHTML = this.getCloseBoxImg_();

        this.div_.appendChild(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");

};



/**

 * Sets the zIndex style for the InfoBox.

 * @param {number} index

 */

InfoBox.prototype.setZIndex = function (index) {



  this.zIndex_ = index;



  if (this.div_) {



    this.div_.style.zIndex = index;

  }



  /**

   * This event is fired when the zIndex of the InfoBox changes.

   * @name InfoBox#zindex_changed

   * @event

   */

  google.maps.event.trigger(this, "zindex_changed");

};



/**

 * Returns the content of the InfoBox.

 * @returns {string}

 */

InfoBox.prototype.getContent = function () {



  return this.content_;

};



/**

 * Returns the geographic location of the InfoBox.

 * @returns {LatLng}

 */

InfoBox.prototype.getPosition = function () {



  return this.position_;

};



/**

 * Returns the zIndex for the InfoBox.

 * @returns {number}

 */

InfoBox.prototype.getZIndex = function () {



  return this.zIndex_;

};



/**

 * Shows the InfoBox.

 */

InfoBox.prototype.show = function () {



  this.isHidden_ = false;

  if (this.div_) {

    this.div_.style.visibility = "visible";

  }

};



/**

 * Hides the InfoBox.

 */

InfoBox.prototype.hide = function () {



  this.isHidden_ = true;

  if (this.div_) {

    this.div_.style.visibility = "hidden";

  }

};



/**

 * Adds the InfoBox to the specified map or Street View panorama. If <tt>anchor</tt>

 *  (usually a <tt>google.maps.Marker</tt>) is specified, the position

 *  of the InfoBox is set to the position of the <tt>anchor</tt>. If the

 *  anchor is dragged to a new location, the InfoBox moves as well.

 * @param {Map|StreetViewPanorama} map

 * @param {MVCObject} [anchor]

 */

InfoBox.prototype.open = function (map, anchor) {



  var me = this;



  if (anchor) {



    this.position_ = anchor.getPosition();

    this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () {

      me.setPosition(this.getPosition());

    });

  }



  this.setMap(map);



  if (this.div_) {



    this.panBox_();

  }

};



/**

 * Removes the InfoBox from the map.

 */

InfoBox.prototype.close = function () {



  if (this.closeListener_) {



    google.maps.event.removeListener(this.closeListener_);

    this.closeListener_ = null;

  }



  if (this.eventListener1_) {



    google.maps.event.removeListener(this.eventListener1_);

    google.maps.event.removeListener(this.eventListener2_);

    google.maps.event.removeListener(this.eventListener3_);

    google.maps.event.removeListener(this.eventListener4_);

    this.eventListener1_ = null;

    this.eventListener2_ = null;

    this.eventListener3_ = null;

    this.eventListener4_ = null;

  }



  if (this.moveListener_) {



    google.maps.event.removeListener(this.moveListener_);

    this.moveListener_ = null;

  }



  if (this.contextListener_) {



    google.maps.event.removeListener(this.contextListener_);

    this.contextListener_ = null;

  }



  this.setMap(null);

};

 

相关的例子

 

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3&amp;sensor=false"></script>

<script type="text/javascript" src="../src/infobox.js"></script>

<script type="text/javascript">

    function initialize() {

        var secheltLoc = new google.maps.LatLng(49.47216, -123.76307);



        var myMapOptions = {

             zoom: 15

            ,center: secheltLoc

            ,mapTypeId: google.maps.MapTypeId.ROADMAP

        };

        var theMap = new google.maps.Map(document.getElementById("map_canvas"), myMapOptions);





        var marker = new google.maps.Marker({

            map: theMap,

            draggable: true,

            position: new google.maps.LatLng(49.47216, -123.76307),

            visible: true

        });



        var boxText = document.createElement("div");

        boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";

        boxText.innerHTML = "City Hall, Sechelt<br>British Columbia<br>Canada";



        var myOptions = {

             content: boxText

            ,disableAutoPan: false

            ,maxWidth: 0

            ,pixelOffset: new google.maps.Size(-140, 0)

            ,zIndex: null

            ,boxStyle: { 

              background: "url('tipbox.gif') no-repeat"

              ,opacity: 0.75

              ,width: "280px"

             }

            ,closeBoxMargin: "10px 2px 2px 2px"

            ,closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif"

            ,infoBoxClearance: new google.maps.Size(1, 1)

            ,isHidden: false

            ,pane: "floatPane"

            ,enableEventPropagation: false

        };



        google.maps.event.addListener(marker, "click", function (e) {

            ib.open(theMap, this);

        });



        var ib = new InfoBox(myOptions);

        ib.open(theMap, marker);

    }

</script>



<title>Creating and Using an InfoBox</title>

</head>

<body onload="initialize()">

    <div id="map_canvas" style="width: 100%; height: 400px"></div>

    <p>

    This example shows the "traditional" use of an InfoBox as a replacement for an InfoWindow.

</body>



</html>

 

同时我是多点连接还需要自动缩放

 

当时网上找的例子的地址:http://www.kankanews.com/ICkengine/archives/131210.shtml

 

不过经过上面的例子只能固定到一定的大小,而且使用infobox.js 插件他的infobox不支持min-Width,所以自己改写了下,下面是整套的源码

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Map.aspx.cs" Inherits="Index_Map" %>



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Locus </title>

    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

    <script type="text/javascript" src="mapfiles/mapapi.js"></script>

    <script src="mapfiles/infobox/infobox.js" type="text/javascript"></script>

    <script type="text/javascript" src="javascript/Cookie.js"></script>

    <script type="text/javascript">



        var str=getCookie("GoogelMap"); //这是一字符串

        delCookie("GoogelMap");

        var strs= new Array(); //定义一数组

        var latstrs= new Array(); //定义一数组

        var locations = new Array(); //定义一数组

     

        var fly="icon/fly.png";  

        var point="icon/point.png"; 

        var land="icon/land.png";

   

        if(str!=null)

        {

            strs=str.split("|"); //字符分割 

            for (i=0;i<strs.length ;i++ )    

            {            

                latstrs=strs[i].split("-"); //字符分割  

                for(j=0;j<latstrs.length;j++)

                {   

                    var GooglePoint = new Array();

                    GooglePoint["lat"]=latstrs[1].replace("<a>","").replace("</a>","");

                    GooglePoint["lon"]=latstrs[2].replace("<a>","").replace("</a>","");

                    GooglePoint["title"]=latstrs[0].replace("<a>","").replace("</a>","");

                    GooglePoint["html"]=latstrs[0].replace("<a>","").replace("</a>","");  

                         

                    if(i==0)

                    {             

                        GooglePoint["icon"]=fly;                        

                        locations.push(GooglePoint);

                        break;

                    }

                    else if(i==strs.length-1)

                    { 

                       GooglePoint["icon"]=land;              

                       locations.push(GooglePoint);

                       break;

                    }

                    else

                    { 

                       GooglePoint["icon"]=point;                       

                       locations.push(GooglePoint);

                       break;

                    }           

                }              

            }   

        }

        else

        {          

           <%=getlocations()%>;          

        }

        

        //地图

        var map;

        var infoWindow

        var marker;

        var poly;



        var defaultZoom = 9;



        /* 加载地图 */

        function initialize() {

            var latlng = new google.maps.LatLng(39.90403, 116.407526);

            var myOptions = {

                zoom: defaultZoom,    //缩放级别

                center: latlng,        //坐标

                mapTypeId: google.maps.MapTypeId.ROADMAP    //类型:默认的普通二维图块

            };

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



            //设置地图缩放

            var i=locations.length;

            var bounds = new google.maps.LatLngBounds();

            while(i--){

                bounds.extend(new   google.maps.LatLng(locations[i]["lat"],locations[i]["lon"]));

            }

            map.fitBounds(bounds);





            // 线条设置

            var polyOptions = {

                strokeColor: '#2e2df9',    // 颜色

                strokeOpacity: 1.0,    // 透明度

                strokeWeight: 2    // 宽度

            }

            poly = new google.maps.Polyline(polyOptions);

            poly.setMap(map);    // 装载





            /* 循环标出所有坐标 */

            for (var i = 0; i < locations.length; i++) {

                //var loc = locations[i].split(',');

                var loc = locations[i];



                var path = poly.getPath();    //获取线条的坐标

                path.push(new google.maps.LatLng(loc["lat"], loc["lon"]));    //为线条添加标记坐标

                //生成标记图标

                marker = new google.maps.Marker({

                    position: new google.maps.LatLng(loc["lat"], loc["lon"]),

                    map: map,

                    icon: loc["icon"],

                    title:loc["title"]

                                });



                AddInfoBox(marker, map);

            }

        }



        function AddInfoBox(marker, map) {

            var boxText = document.createElement("div");

            boxText.style.cssText = "border: 1px solid #999894; margin-top: 9px; background: #f5f5f5; padding:3px 5px;font-size:12px;font-family:'宋体';height:15px;line-height:15px;text-align:center";

            //设置宽度,取出字符长度*6

            var ssize = GetLength(marker.title)*6;

            boxText.style.width = ssize + "px";

            boxText.innerHTML = marker.title;



            var myOptions = { 

                content: boxText, 

                maxWidth: 0, 

                disableAutoPan: false,

                 pixelOffset: new google.maps.Size(15, -40),

                  boxClass:"shop_location" ,

                  closeBoxURL: "" ,

                  infoBoxClearance: new google.maps.Size(1, 1) ,

                  isHidden: false ,

                  pane: "floatPane" ,

                  enableEventPropagation: false ,

                  maxWidth: ssize + 12

                  };

                   

            google.maps.event.addListener(marker, "click", function (e) {

//                var ib = new InfoBox(myOptions);

                ib.open(map, this);

            });

            var ib = new InfoBox(myOptions);

            ib.open(map, marker);

        }



        function GetLength (str) {

            ///<summary>获得字符串实际长度,中文2,英文1</summary>

            ///<param name="str">要获得长度的字符串</param>

            var realLength = 0, len = str.length, charCode = -1;

            for (var i = 0; i < len; i++) {

                charCode = str.charCodeAt(i);

                if (charCode >= 0 && charCode <= 128) realLength += 1;

                else realLength += 2;

            }

            return realLength;

        };

    </script>

</head>

<body onload="initialize()">

    <form id="form1" runat="server">

    <div>

        <div id="map_canvas" style="width: 724px; height: 479px;">

        </div>

    </div>

    </form>

</body>

</html>

infobox.js 也需要改写

/**

* @name InfoBox

* @version 1.1.9 [October 2, 2011]

* @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google)

* @copyright Copyright 2010 Gary Little [gary at luxcentral.com]

* @fileoverview InfoBox extends the Google Maps JavaScript API V3 <tt>OverlayView</tt> class.

*  <p>

*  An InfoBox behaves like a <tt>google.maps.InfoWindow</tt>, but it supports several

*  additional properties for advanced styling. An InfoBox can also be used as a map label.

*  <p>

*  An InfoBox also fires the same events as a <tt>google.maps.InfoWindow</tt>.

*  <p>

*  Browsers tested:

*  <p>

*  Mac -- Safari (4.0.4), Firefox (3.6), Opera (10.10), Chrome (4.0.249.43), OmniWeb (5.10.1)

*  <br>

*  Win -- Safari, Firefox, Opera, Chrome (3.0.195.38), Internet Explorer (8.0.6001.18702)

*  <br>

*  iPod Touch/iPhone -- Safari (3.1.2)

*/



/*!

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*       http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/



/*jslint browser:true */

/*global google */



/**

* @name InfoBoxOptions

* @class This class represents the optional parameter passed to the {@link InfoBox} constructor.

* @property {string|Node} content The content of the InfoBox (plain text or an HTML DOM node).

* @property {boolean} disableAutoPan Disable auto-pan on <tt>open</tt> (default is <tt>false</tt>).

* @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum.

* @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox

*  (or the bottom left corner if the <code>alignBottom</code> property is <code>true</code>)

*  to the map pixel corresponding to <tt>position</tt>.

* @property {LatLng} position The geographic location at which to display the InfoBox.

* @property {number} zIndex The CSS z-index style value for the InfoBox.

*  Note: This value overrides a zIndex setting specified in the <tt>boxStyle</tt> property.

* @property {string} boxClass The name of the CSS class defining the styles for the InfoBox container.

*  The default name is <code>infoBox</code>.

* @property {Object} [boxStyle] An object literal whose properties define specific CSS

*  style values to be applied to the InfoBox. Style values defined here override those that may

*  be defined in the <code>boxClass</code> style sheet. If this property is changed after the

*  InfoBox has been created, all previously set styles (except those defined in the style sheet)

*  are removed from the InfoBox before the new style values are applied.

* @property {string} closeBoxMargin The CSS margin style value for the close box.

*  The default is "2px" (a 2-pixel margin on all sides).

* @property {string} closeBoxURL The URL of the image representing the close box.

*  Note: The default is the URL for Google's standard close box.

*  Set this property to "" if no close box is required.

* @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the

*  map edge after an auto-pan.

* @property {boolean} isHidden Hide the InfoBox on <tt>open</tt> (default is <tt>false</tt>).

* @property {boolean} alignBottom Align the bottom left corner of the InfoBox to the <code>position</code>

*  location (default is <tt>false</tt> which means that the top left corner of the InfoBox is aligned).

* @property {string} pane The pane where the InfoBox is to appear (default is "floatPane").

*  Set the pane to "mapPane" if the InfoBox is being used as a map label.

*  Valid pane names are the property names for the <tt>google.maps.MapPanes</tt> object.

* @property {boolean} enableEventPropagation Propagate mousedown, click, dblclick,

*  and contextmenu events in the InfoBox (default is <tt>false</tt> to mimic the behavior

*  of a <tt>google.maps.InfoWindow</tt>). Set this property to <tt>true</tt> if the InfoBox

*  is being used as a map label. iPhone note: This property setting has no effect; events are

*  always propagated.

*/



/**

* Creates an InfoBox with the options specified in {@link InfoBoxOptions}.

*  Call <tt>InfoBox.open</tt> to add the box to the map.

* @constructor

* @param {InfoBoxOptions} [opt_opts]

*/

function InfoBox(opt_opts) {



    opt_opts = opt_opts || {};



    google.maps.OverlayView.apply(this, arguments);



    // Standard options (in common with google.maps.InfoWindow):

    //

    this.content_ = opt_opts.content || "";

    this.disableAutoPan_ = opt_opts.disableAutoPan || false;

    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.boxClass_ = opt_opts.boxClass || "infoBox";

    this.boxStyle_ = opt_opts.boxStyle || {};

    //2014/10/20 luoc 去掉关闭

    this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px";

    //this.closeBoxURL_ = opt_opts.closeBoxURL || "http://www.google.com/intl/en_us/mapfiles/close.gif";

    this.closeBoxURL_ = ""

    if (opt_opts.closeBoxURL === "") {

        this.closeBoxURL_ = "";

    }

    this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1);

    this.isHidden_ = opt_opts.isHidden || false;

    this.alignBottom_ = opt_opts.alignBottom || false;

    this.pane_ = opt_opts.pane || "floatPane";

    this.enableEventPropagation_ = opt_opts.enableEventPropagation || false;



    this.div_ = null;

    this.closeListener_ = null;

    this.eventListener1_ = null;

    this.eventListener2_ = null;

    this.eventListener3_ = null;

    this.moveListener_ = 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;

    var 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_) {



            cancelHandler(e);

        }

    };



    if (!this.div_) {



        this.div_ = document.createElement("div");



        this.setBoxStyle_();



        if (typeof this.content_.nodeType === "undefined") {

            //2014/10/20 luoc 去掉关闭

            //this.div_.innerHTML = this.getCloseBoxImg_() + this.content_;

            this.div_.innerHTML = this.content_;

        } else {

            this.div_.innerHTML = this.getCloseBoxImg_();

            this.div_.appendChild(this.content_);

        }



        // 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.div_.style.overflow = "hidden";

                this.fixedWidthSet_ = true;



            }

            else {

                this.div_.style.width = this.maxWidth_ + "px";

                this.fixedWidthSet_ = false;

            }

            //2014/10/21 luoc 原来不用根据传过来的maxWidth 设置宽度

//            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;

//            }

        }



        this.panBox_(this.disableAutoPan_);



        if (!this.enableEventPropagation_) {



            // Cancel event propagation.

            //

            this.eventListener1_ = google.maps.event.addDomListener(this.div_, "mousedown", cancelHandler);

            this.eventListener2_ = google.maps.event.addDomListener(this.div_, "click", cancelHandler);

            this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", cancelHandler);

            this.eventListener4_ = google.maps.event.addDomListener(this.div_, "mouseover", function (e) {

                this.style.cursor = "default";

            });

        }



        this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler);



        /**

        * This event is fired when the DIV containing the InfoBox's content is attached to the DOM.

        * @name InfoBox#domready

        * @event

        */

        google.maps.event.trigger(this, "domready");

    }

};



/**

* Returns the HTML <IMG> tag for the close box.

* @private

*/

InfoBox.prototype.getCloseBoxImg_ = function () {



    var img = "";



    if (this.closeBoxURL_ !== "") {



        img = "<img";

        img += " src='" + this.closeBoxURL_ + "'";

        img += " align=right"; // Do this because Opera chokes on style='float: right;'

        img += " style='";

        img += " position: relative;"; // Required by MSIE

        img += " cursor: pointer;";

        img += " margin: " + this.closeBoxMargin_ + ";";

        img += "'>";

    }



    return img;

};



/**

* Adds the click handler to the InfoBox close box.

* @private

*/

InfoBox.prototype.addClickHandler_ = function () {



    var closeBox;



    if (this.closeBoxURL_ !== "") {



        closeBox = this.div_.firstChild;

        this.closeListener_ = google.maps.event.addDomListener(closeBox, 'click', this.getCloseClickHandler_());



    } else {



        this.closeListener_ = null;

    }

};



/**

* Returns the function to call when the user clicks the close box of an InfoBox.

* @private

*/

InfoBox.prototype.getCloseClickHandler_ = function () {



    var me = this;



    return function (e) {



        // 1.0.3 fix: Always prevent propagation of a close box click to the map:

        e.cancelBubble = true;



        if (e.stopPropagation) {



            e.stopPropagation();

        }



        me.close();



        /**

        * This event is fired when the InfoBox's close box is clicked.

        * @name InfoBox#closeclick

        * @event

        */

        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) {



    var map;

    var bounds;

    var xOffset = 0, yOffset = 0;



    if (!disablePan) {



        map = this.getMap();



        if (map instanceof google.maps.Map) { // Only pan if attached to map, not panorama



            if (!map.getBounds().contains(this.position_)) {

                // Marker not in visible area of map, so set center

                // of map to the marker position first.

                map.setCenter(this.position_);

            }



            bounds = map.getBounds();



            var mapDiv = map.getDiv();

            var mapWidth = mapDiv.offsetWidth;

            var mapHeight = mapDiv.offsetHeight;

            var iwOffsetX = this.pixelOffset_.width;

            var iwOffsetY = this.pixelOffset_.height;

            var iwWidth = this.div_.offsetWidth;

            var iwHeight = this.div_.offsetHeight;

            var padX = this.infoBoxClearance_.width;

            var padY = this.infoBoxClearance_.height;

            var pixPosition = this.getProjection().fromLatLngToContainerPixel(this.position_);



            if (pixPosition.x < (-iwOffsetX + padX)) {

                xOffset = pixPosition.x + iwOffsetX - padX;

            } else if ((pixPosition.x + iwWidth + iwOffsetX + padX) > mapWidth) {

                xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth;

            }

            if (this.alignBottom_) {

                if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) {

                    yOffset = pixPosition.y + iwOffsetY - padY - iwHeight;

                } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) {

                    yOffset = pixPosition.y + iwOffsetY + padY - mapHeight;

                }

            } else {

                if (pixPosition.y < (-iwOffsetY + padY)) {

                    yOffset = pixPosition.y + iwOffsetY - padY;

                } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) {

                    yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight;

                }

            }



            if (!(xOffset === 0 && yOffset === 0)) {



                // Move the map to the shifted center.

                //

                var c = map.getCenter();

                map.panBy(xOffset, yOffset);

            }

        }

    }

};



/**

* Sets the style of the InfoBox by setting the style sheet and applying

* other specific styles requested.

* @private

*/

InfoBox.prototype.setBoxStyle_ = function () {



    var i, boxStyle;



    if (this.div_) {



        // Apply style values from the style sheet defined in the boxClass parameter:

        this.div_.className = this.boxClass_;



        // Clear existing inline style values:

        this.div_.style.cssText = "";



        // Apply style values defined in the boxStyle parameter:

        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.opacity !== "") {



            this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")";

        }



        // Apply required styles:

        //

        this.div_.style.position = "absolute";

        this.div_.style.visibility = 'hidden';

        if (this.zIndex_ !== null) {



            this.div_.style.zIndex = this.zIndex_;

        }

    }

};



/**

* 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.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.pixelOffset_.width) + "px";



    if (this.alignBottom_) {

        this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px";

    } else {

        this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px";

    }



    if (this.isHidden_) {



        this.div_.style.visibility = 'hidden';



    } else {



        this.div_.style.visibility = "visible";

    }

};



/**

* Sets the options for the InfoBox. Note that changes to the <tt>maxWidth</tt>,

*  <tt>closeBoxMargin</tt>, <tt>closeBoxURL</tt>, and <tt>enableEventPropagation</tt>

*  properties have no affect until the current InfoBox is <tt>close</tt>d and a new one

*  is <tt>open</tt>ed.

* @param {InfoBoxOptions} opt_opts

*/

InfoBox.prototype.setOptions = function (opt_opts) {

    if (typeof opt_opts.boxClass !== "undefined") { // Must be first



        this.boxClass_ = opt_opts.boxClass;

        this.setBoxStyle_();

    }

    if (typeof opt_opts.boxStyle !== "undefined") { // Must be second



        this.boxStyle_ = opt_opts.boxStyle;

        this.setBoxStyle_();

    }

    if (typeof opt_opts.content !== "undefined") {



        this.setContent(opt_opts.content);

    }

    if (typeof opt_opts.disableAutoPan !== "undefined") {



        this.disableAutoPan_ = opt_opts.disableAutoPan;

    }

    if (typeof opt_opts.maxWidth !== "undefined") {



        this.maxWidth_ = opt_opts.maxWidth;

    }

    if (typeof opt_opts.pixelOffset !== "undefined") {



        this.pixelOffset_ = opt_opts.pixelOffset;

    }

    if (typeof opt_opts.alignBottom !== "undefined") {



        this.alignBottom_ = opt_opts.alignBottom;

    }

    if (typeof opt_opts.position !== "undefined") {



        this.setPosition(opt_opts.position);

    }

    if (typeof opt_opts.zIndex !== "undefined") {



        this.setZIndex(opt_opts.zIndex);

    }

    if (typeof opt_opts.closeBoxMargin !== "undefined") {



        this.closeBoxMargin_ = opt_opts.closeBoxMargin;

    }

    if (typeof opt_opts.closeBoxURL !== "undefined") {



        this.closeBoxURL_ = opt_opts.closeBoxURL;

    }

    if (typeof opt_opts.infoBoxClearance !== "undefined") {



        this.infoBoxClearance_ = opt_opts.infoBoxClearance;

    }

    if (typeof opt_opts.isHidden !== "undefined") {



        this.isHidden_ = opt_opts.isHidden;

    }

    if (typeof opt_opts.enableEventPropagation !== "undefined") {



        this.enableEventPropagation_ = opt_opts.enableEventPropagation;

    }



    if (this.div_) {



        this.draw();

    }

};



/**

* Sets the content of the InfoBox.

*  The content can be plain text or an HTML DOM node.

* @param {string|Node} content

*/

InfoBox.prototype.setContent = function (content) {

    this.content_ = content;



    if (this.div_) {



        if (this.closeListener_) {



            google.maps.event.removeListener(this.closeListener_);

            this.closeListener_ = null;

        }



        // Odd code required to make things work with MSIE.

        //

        if (!this.fixedWidthSet_) {



            this.div_.style.width = "";

        }



        if (typeof content.nodeType === "undefined") {

            this.div_.innerHTML = this.getCloseBoxImg_() + content;

        } else {

            this.div_.innerHTML = this.getCloseBoxImg_();

            this.div_.appendChild(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";

            if (typeof content.nodeType === "undefined") {

                this.div_.innerHTML = this.getCloseBoxImg_() + content;

            } else {

                this.div_.innerHTML = this.getCloseBoxImg_();

                this.div_.appendChild(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");

};



/**

* Sets the zIndex style for the InfoBox.

* @param {number} index

*/

InfoBox.prototype.setZIndex = function (index) {



    this.zIndex_ = index;



    if (this.div_) {



        this.div_.style.zIndex = index;

    }



    /**

    * This event is fired when the zIndex of the InfoBox changes.

    * @name InfoBox#zindex_changed

    * @event

    */

    google.maps.event.trigger(this, "zindex_changed");

};



/**

* Returns the content of the InfoBox.

* @returns {string}

*/

InfoBox.prototype.getContent = function () {



    return this.content_;

};



/**

* Returns the geographic location of the InfoBox.

* @returns {LatLng}

*/

InfoBox.prototype.getPosition = function () {



    return this.position_;

};



/**

* Returns the zIndex for the InfoBox.

* @returns {number}

*/

InfoBox.prototype.getZIndex = function () {



    return this.zIndex_;

};



/**

* Shows the InfoBox.

*/

InfoBox.prototype.show = function () {



    this.isHidden_ = false;

    if (this.div_) {

        this.div_.style.visibility = "visible";

    }

};



/**

* Hides the InfoBox.

*/

InfoBox.prototype.hide = function () {



    this.isHidden_ = true;

    if (this.div_) {

        this.div_.style.visibility = "hidden";

    }

};



/**

* Adds the InfoBox to the specified map or Street View panorama. If <tt>anchor</tt>

*  (usually a <tt>google.maps.Marker</tt>) is specified, the position

*  of the InfoBox is set to the position of the <tt>anchor</tt>. If the

*  anchor is dragged to a new location, the InfoBox moves as well.

* @param {Map|StreetViewPanorama} map

* @param {MVCObject} [anchor]

*/

InfoBox.prototype.open = function (map, anchor) {



    var me = this;



    if (anchor) {



        this.position_ = anchor.getPosition();

        this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () {

            me.setPosition(this.getPosition());

        });

    }



    this.setMap(map);



    if (this.div_) {



        this.panBox_();

    }

};



/**

* Removes the InfoBox from the map.

*/

InfoBox.prototype.close = function () {



    if (this.closeListener_) {



        google.maps.event.removeListener(this.closeListener_);

        this.closeListener_ = null;

    }



    if (this.eventListener1_) {



        google.maps.event.removeListener(this.eventListener1_);

        google.maps.event.removeListener(this.eventListener2_);

        google.maps.event.removeListener(this.eventListener3_);

        google.maps.event.removeListener(this.eventListener4_);

        this.eventListener1_ = null;

        this.eventListener2_ = null;

        this.eventListener3_ = null;

        this.eventListener4_ = null;

    }



    if (this.moveListener_) {



        google.maps.event.removeListener(this.moveListener_);

        this.moveListener_ = null;

    }



    if (this.contextListener_) {



        google.maps.event.removeListener(this.contextListener_);

        this.contextListener_ = null;

    }



    this.setMap(null);

};

 

你可能感兴趣的:(google map)