zoukankan      html  css  js  c++  java
  • 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
                  , "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=" 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=" 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);
    };
  • 相关阅读:
    Visual Studio 常用快捷键 (二)
    Visual Studio 常用快捷键
    页游体验
    JSFL 工具
    GhostCat工具
    如何制作一个塔防游戏
    水墨
    给 想转2dx 却无从下手的aser
    两岸三地在线编程学习网站大全
    as3反射应用及简要代码
  • 原文地址:https://www.cnblogs.com/mvv118/p/4044996.html
Copyright © 2011-2022 走看看