天天看點

2021年在vue中使用 Google Map

目前在vue中使用google map有以下兩種方法:

一、使用 JavaScript 建立地圖執行個體

該方法優點在于可配置項多,友善自定義,缺點是較複雜,且文檔為英文,有一定學習難度。

在開始之前確定你已經在

https://console.cloud.google.com/google/maps-apis/overview

(谷歌地圖API官網)建立賬戶、開通并啟用以下API,最後擷取到你的Google Map JavaScript API Key,并且有科學上網的辦法

2021年在vue中使用 Google Map
Directions API 為路徑規劃API,而Maps JavaScript API是基礎地圖展示所需的API

然後在

index.html

head

标簽中引入

如果不在 head 标簽中引入的話會出現建立地圖時用到的方法未定義的問題,是以需要先使檔案加載完成後再初始化地圖

國内通路的話目前是沒有辦法的

<script src="http://ditu.google.cn/maps/api/js?&key=YOUR_KEY"></script> // 國内通路方式,已不再支援
           
YOUR_KEY 為你的API Key

在你的vue檔案中,建立一個 id 為 gMap 的

div

,并且指定寬度和高度,不然會無法顯示。然後建立

initMap

方法來初始化地圖執行個體,最後在

mounted

鈎子函數中調用,不然容易出現 google undefined 的錯誤

圖例(僅供參考):

2021年在vue中使用 Google Map

代碼:

<template>
	<div class="map-main" id="gMap"></div>
</template>
<script>
    // MarkerWithLabel.js 如果引入不生效的話,可以把内容複制到這裡
	export default {
    name: 'FB_map',
    data() {
        map: null,
        markers:[
            {
                name: 'william',
                url: require('../../assets/signIn.png'),
                position: {
                  lat: 45.51118967089818,
                  lng: -73.63236753474335
                }
          }
        ]
    },
    mounted() {
        this.initMap() // vue執行個體挂載完成後初始化地圖
    },
    methods: {
        initMap() {
            this.map = new google.maps.Map(document.getElementById('gMap'), {
              zoom: 12, // 縮放的數值
              center: this.markers[0].position, // 将第一個marker的坐标作為地圖中心的坐标點
              mapTypeId: google.maps.MapTypeId.ROADMAP // 地圖類别
            });
            // 周遊标記的數組
            this.markers.map(item => {
              let marker = new MarkerWithLabel({
                position: item.position,
                icon: {
                  url: require('../../assets/signIn.png'), // 你的 icon 路徑
                  scaledSize: new google.maps.Size(60, 60), // icon 的位置
                  //origin: new google.maps.Point(0, 0), // origin
                  // labelOrigin: { x: 25, y: 50} // label 的位置
                },
                draggable: false, // 是否可拖動
                map: this.map, // 綁定的地圖執行個體
                labelAnchor: new google.maps.Point(30, 60), // label 的位置
                labelClass: '' // label 的 class
              });
              marker.addListener("click", () => { // 為标記添加點選事件
                map.setCenter(item.position) // 每次點選标記會将地圖的中心定位到标記
                marker.set('labelClass', 'labels'); // 每次點選标記會設定label的class為labels
              })
              // var infowindow = new google.maps.InfoWindow({  // 資訊視窗
              //   content: item.name
              // });
              // marker.addListener("mouseover", () => { // hover 觸發資訊視窗
              //   infowindow.open(this.map, marker);
              // });
              // marker.addListener("mouseout", () => {
              //   infowindow.close(this.map, marker);
              // });
            })
    	}
      },
    }
</script>
<style>
  .map-main {
    width: 100%;
    height: 500px;
    border-radius: 10px;
    overflow: hidden;
  }
  .labels { // 如果 labels 樣式不生效看看 style 标簽的 scoped 是否去掉
    height: 52px;
    width: 52px;
    border-radius: 50%;
    border: 4px solid #6c62db;
  }

</style>
           

二、使用vue2-google-maps

該方法優點在于使用友善,無需使用 js 建立地圖的執行個體,缺點在于自定義範圍小,如無法自定義

label

的樣式

1.安裝

在開始前我們需要安裝一下相關依賴:

npm install vue2-google-maps
           

2.配置

然後到

main.js

檔案中,添加如下配置:

import * as VueGoogleMaps from 'vue2-google-maps'
Vue.use(VueGoogleMaps, {
    load: {
      key: "YOUR_API_KEY"
    }
})

           
YOUR_KEY 為你的API Key

3.使用

接下來就可以在你的vue檔案中正常使用了,注意不同于使用JavaScript建立地圖執行個體,我們使用到了

vue2-google-maps

中自帶的元件

<GmapMap>

以及

<GmapMarker>

圖例:

2021年在vue中使用 Google Map

代碼(無需使用 js 建立地圖執行個體):

<template>
  <div class="map-container">
    <div class="map-main">
      <GmapMap :center='center' :zoom='12' ref="mapRef" class="map-main">
        <GmapMarker @dragend="updateMaker" :key="index" v-for="(marker, index) in markers" :position="marker.position" :clickable="true" :icon="marker.markerData" @click="center=marker.position" class="map-marker" :label="marker.label"></GmapMarker>
      </GmapMap>
        <!--
		label:需要傳入圖示的标簽配置
		position:需要傳入地圖示記的坐标
		clickable:需要傳入布爾類型的值,控制地圖示記是否可以點選
		icon:地圖示記的圖示路徑
		@click:标記點選事件
		@dragend:拖動結束觸發事件
		-->
    </div>
<template>
    
<script>
  export default {
    name: 'FB_map',
    data() {
      return {
        markers: [
          {
            markerData: {
              url: require('../../assets/signIn.png'),
              size: {width: 60, height: 60, f: 'px', b: 'px',},
              scaledSize: {width: 60, height: 60, f: 'px', b: 'px',},
              labelOrigin: {x: 16, y: -10}
            },
            label: 'label',
            position: {
              lat: 45.53317193016025,
              lng: -73.58580366167472
            }
          },
          {
            markerData: {
              url: require('../../assets/logo.png'),
              scaledSize: {width: 50, height: 50, f: 'px', b: 'px',}
            },
            label: {
              text: 'label',
              color: "black",
              fontWeight: "bold",
              fontSize: "12px"
            },
            title: 'fff',
            position: {
              lat: 45.49118967089818,
              lng: -73.62236753474335
            }
          }
        ],
        center: {
          lat: 45.508,
          lng: -73.587
        }
      };
    }
  }

</script>
           

三、總結

方法 優點 缺點
JavaScript建立地圖執行個體 可以詳細自定義地圖的各項配置,有官方文檔以及海量部落格來幫助學習和配置 相比另一種方法較為複雜,需要踩的坑也比較多
使用vue2-google-maps 上手簡單,配置項雖然少但友善操作 配置項少,比如無法操作label樣式,相關問題解決的部落格相比起來比較少

四、

MarkerWithLabel.js

源代碼

/**
   * @name MarkerWithLabel for V3
   * @version 1.1.8 [February 26, 2013]
   * @author Gary Little (inspired by code from Marc Ridey of Google).
   * @copyright Copyright 2012 Gary Little [gary at luxcentral.com]
   * @fileoverview MarkerWithLabel extends the Google Maps JavaScript API V3
   *  <code>google.maps.Marker</code> class.
   *  <p>
   *  MarkerWithLabel allows you to define markers with associated labels. As you would expect,
   *  if the marker is draggable, so too will be the label. In addition, a marker with a label
   *  responds to all mouse events in the same manner as a regular marker. It also fires mouse
   *  events and "property changed" events just as a regular marker would. Version 1.1 adds
   *  support for the raiseOnDrag feature introduced in API V3.3.
   *  <p>
   *  If you drag a marker by its label, you can cancel the drag and return the marker to its
   *  original position by pressing the <code>Esc</code> key. This doesn't work if you drag the marker
   *  itself because this feature is not (yet) supported in the <code>google.maps.Marker</code> class.
   */

  /*!
   *
   * 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 document,google */

  /**
   * @param {Function} childCtor Child class.
   * @param {Function} parentCtor Parent class.
   */
   function inherits(childCtor, parentCtor) {
    /** @constructor */
    function tempCtor() {};
    tempCtor.prototype = parentCtor.prototype;
    childCtor.superClass_ = parentCtor.prototype;
    childCtor.prototype = new tempCtor();
    /** @override */
    childCtor.prototype.constructor = childCtor;
}

/**
 * This constructor creates a label and associates it with a marker.
 * It is for the private use of the MarkerWithLabel class.
 * @constructor
 * @param {Marker} marker The marker with which the label is to be associated.
 * @param {string} crossURL The URL of the cross image =.
 * @param {string} handCursor The URL of the hand cursor.
 * @private
 */
function MarkerLabel_(marker, crossURL, handCursorURL) {
    this.marker_ = marker;
    this.handCursorURL_ = marker.handCursorURL;

    this.labelDiv_ = document.createElement("div");
    this.labelDiv_.style.cssText = "position: absolute; overflow: hidden;";

    // Set up the DIV for handling mouse events in the label. This DIV forms a transparent veil
    // in the "overlayMouseTarget" pane, a veil that covers just the label. This is done so that
    // events can be captured even if the label is in the shadow of a google.maps.InfoWindow.
    // Code is included here to ensure the veil is always exactly the same size as the label.
    this.eventDiv_ = document.createElement("div");
    this.eventDiv_.style.cssText = this.labelDiv_.style.cssText;

    // This is needed for proper behavior on MSIE:
    this.eventDiv_.setAttribute("onselectstart", "return false;");
    this.eventDiv_.setAttribute("ondragstart", "return false;");

    // Get the DIV for the "X" to be displayed when the marker is raised.
    this.crossDiv_ = MarkerLabel_.getSharedCross(crossURL);
}
inherits(MarkerLabel_, google.maps.OverlayView);

/**
 * Returns the DIV for the cross used when dragging a marker when the
 * raiseOnDrag parameter set to true. One cross is shared with all markers.
 * @param {string} crossURL The URL of the cross image =.
 * @private
 */
MarkerLabel_.getSharedCross = function (crossURL) {
    var div;
    if (typeof MarkerLabel_.getSharedCross.crossDiv === "undefined") {
        div = document.createElement("img");
        div.style.cssText = "position: absolute; z-index: 1000002; display: none;";
        // Hopefully Google never changes the standard "X" attributes:
        div.style.marginLeft = "-8px";
        div.style.marginTop = "-9px";
        div.src = crossURL;
        MarkerLabel_.getSharedCross.crossDiv = div;
    }
    return MarkerLabel_.getSharedCross.crossDiv;
};

/**
 * Adds the DIV representing the label to the DOM. This method is called
 * automatically when the marker's <code>setMap</code> method is called.
 * @private
 */
MarkerLabel_.prototype.onAdd = function () {
    var me = this;
    var cMouseIsDown = false;
    var cDraggingLabel = false;
    var cSavedZIndex;
    var cLatOffset, cLngOffset;
    var cIgnoreClick;
    var cRaiseEnabled;
    var cStartPosition;
    var cStartCenter;
    // Constants:
    var cRaiseOffset = 20;
    var cDraggingCursor = "url(" + this.handCursorURL_ + ")";

    // Stops all processing of an event.
    //
    var cAbortEvent = function (e) {
        if (e.preventDefault) {
            e.preventDefault();
        }
        e.cancelBubble = true;
        if (e.stopPropagation) {
            e.stopPropagation();
        }
    };

    var cStopBounce = function () {
        me.marker_.setAnimation(null);
    };

    this.getPanes().overlayImage.appendChild(this.labelDiv_);
    this.getPanes().overlayMouseTarget.appendChild(this.eventDiv_);
    // One cross is shared with all markers, so only add it once:
    if (typeof MarkerLabel_.getSharedCross.processed === "undefined") {
        this.getPanes().overlayImage.appendChild(this.crossDiv_);
        MarkerLabel_.getSharedCross.processed = true;
    }

    this.listeners_ = [
        google.maps.event.addDomListener(this.eventDiv_, "mouseover", function (e) {
            if (me.marker_.getDraggable() || me.marker_.getClickable()) {
                this.style.cursor = "pointer";
                google.maps.event.trigger(me.marker_, "mouseover", e);
            }
        }),
        google.maps.event.addDomListener(this.eventDiv_, "mouseout", function (e) {
            if ((me.marker_.getDraggable() || me.marker_.getClickable()) && !cDraggingLabel) {
                this.style.cursor = me.marker_.getCursor();
                google.maps.event.trigger(me.marker_, "mouseout", e);
            }
        }),
        google.maps.event.addDomListener(this.eventDiv_, "mousedown", function (e) {
            cDraggingLabel = false;
            if (me.marker_.getDraggable()) {
                cMouseIsDown = true;
                this.style.cursor = cDraggingCursor;
            }
            if (me.marker_.getDraggable() || me.marker_.getClickable()) {
                google.maps.event.trigger(me.marker_, "mousedown", e);
                cAbortEvent(e); // Prevent map pan when starting a drag on a label
            }
        }),
        google.maps.event.addDomListener(document, "mouseup", function (mEvent) {
            var position;
            if (cMouseIsDown) {
                cMouseIsDown = false;
                me.eventDiv_.style.cursor = "pointer";
                google.maps.event.trigger(me.marker_, "mouseup", mEvent);
            }
            if (cDraggingLabel) {
                if (cRaiseEnabled) { // Lower the marker & label
                    position = me.getProjection().fromLatLngToDivPixel(me.marker_.getPosition());
                    position.y += cRaiseOffset;
                    me.marker_.setPosition(me.getProjection().fromDivPixelToLatLng(position));
                    // This is not the same bouncing style as when the marker portion is dragged,
                    // but it will have to do:
                    try { // Will fail if running Google Maps API earlier than V3.3
                        me.marker_.setAnimation(google.maps.Animation.BOUNCE);
                        setTimeout(cStopBounce, 1406);
                    } catch (e) {}
                }
                me.crossDiv_.style.display = "none";
                me.marker_.setZIndex(cSavedZIndex);
                cIgnoreClick = true; // Set flag to ignore the click event reported after a label drag
                cDraggingLabel = false;
                mEvent.latLng = me.marker_.getPosition();
                google.maps.event.trigger(me.marker_, "dragend", mEvent);
            }
        }),
        google.maps.event.addListener(me.marker_.getMap(), "mousemove", function (mEvent) {
            var position;
            if (cMouseIsDown) {
                if (cDraggingLabel) {
                    // Change the reported location from the mouse position to the marker position:
                    mEvent.latLng = new google.maps.LatLng(mEvent.latLng.lat() - cLatOffset, mEvent.latLng.lng() - cLngOffset);
                    position = me.getProjection().fromLatLngToDivPixel(mEvent.latLng);
                    if (cRaiseEnabled) {
                        me.crossDiv_.style.left = position.x + "px";
                        me.crossDiv_.style.top = position.y + "px";
                        me.crossDiv_.style.display = "";
                        position.y -= cRaiseOffset;
                    }
                    me.marker_.setPosition(me.getProjection().fromDivPixelToLatLng(position));
                    if (cRaiseEnabled) { // Don't raise the veil; this hack needed to make MSIE act properly
                        me.eventDiv_.style.top = (position.y + cRaiseOffset) + "px";
                    }
                    google.maps.event.trigger(me.marker_, "drag", mEvent);
                } else {
                    // Calculate offsets from the click point to the marker position:
                    cLatOffset = mEvent.latLng.lat() - me.marker_.getPosition().lat();
                    cLngOffset = mEvent.latLng.lng() - me.marker_.getPosition().lng();
                    cSavedZIndex = me.marker_.getZIndex();
                    cStartPosition = me.marker_.getPosition();
                    cStartCenter = me.marker_.getMap().getCenter();
                    cRaiseEnabled = me.marker_.get("raiseOnDrag");
                    cDraggingLabel = true;
                    me.marker_.setZIndex(1000000); // Moves the marker & label to the foreground during a drag
                    mEvent.latLng = me.marker_.getPosition();
                    google.maps.event.trigger(me.marker_, "dragstart", mEvent);
                }
            }
        }),
        google.maps.event.addDomListener(document, "keydown", function (e) {
            if (cDraggingLabel) {
                if (e.keyCode === 27) { // Esc key
                    cRaiseEnabled = false;
                    me.marker_.setPosition(cStartPosition);
                    me.marker_.getMap().setCenter(cStartCenter);
                    google.maps.event.trigger(document, "mouseup", e);
                }
            }
        }),
        google.maps.event.addDomListener(this.eventDiv_, "click", function (e) {
            if (me.marker_.getDraggable() || me.marker_.getClickable()) {
                if (cIgnoreClick) { // Ignore the click reported when a label drag ends
                    cIgnoreClick = false;
                } else {
                    google.maps.event.trigger(me.marker_, "click", e);
                    cAbortEvent(e); // Prevent click from being passed on to map
                }
            }
        }),
        google.maps.event.addDomListener(this.eventDiv_, "dblclick", function (e) {
            if (me.marker_.getDraggable() || me.marker_.getClickable()) {
                google.maps.event.trigger(me.marker_, "dblclick", e);
                cAbortEvent(e); // Prevent map zoom when double-clicking on a label
            }
        }),
        google.maps.event.addListener(this.marker_, "dragstart", function (mEvent) {
            if (!cDraggingLabel) {
                cRaiseEnabled = this.get("raiseOnDrag");
            }
        }),
        google.maps.event.addListener(this.marker_, "drag", function (mEvent) {
            if (!cDraggingLabel) {
                if (cRaiseEnabled) {
                    me.setPosition(cRaiseOffset);
                    // During a drag, the marker's z-index is temporarily set to 1000000 to
                    // ensure it appears above all other markers. Also set the label's z-index
                    // to 1000000 (plus or minus 1 depending on whether the label is supposed
                    // to be above or below the marker).
                    me.labelDiv_.style.zIndex = 1000000 + (this.get("labelInBackground") ? -1 : +1);
                }
            }
        }),
        google.maps.event.addListener(this.marker_, "dragend", function (mEvent) {
            if (!cDraggingLabel) {
                if (cRaiseEnabled) {
                    me.setPosition(0); // Also restores z-index of label
                }
            }
        }),
        google.maps.event.addListener(this.marker_, "position_changed", function () {
            me.setPosition();
        }),
        google.maps.event.addListener(this.marker_, "zindex_changed", function () {
            me.setZIndex();
        }),
        google.maps.event.addListener(this.marker_, "visible_changed", function () {
            me.setVisible();
        }),
        google.maps.event.addListener(this.marker_, "labelvisible_changed", function () {
            me.setVisible();
        }),
        google.maps.event.addListener(this.marker_, "title_changed", function () {
            me.setTitle();
        }),
        google.maps.event.addListener(this.marker_, "labelcontent_changed", function () {
            me.setContent();
        }),
        google.maps.event.addListener(this.marker_, "labelanchor_changed", function () {
            me.setAnchor();
        }),
        google.maps.event.addListener(this.marker_, "labelclass_changed", function () {
            me.setStyles();
        }),
        google.maps.event.addListener(this.marker_, "labelstyle_changed", function () {
            me.setStyles();
        })
    ];
};

/**
 * Removes the DIV for the label from the DOM. It also removes all event handlers.
 * This method is called automatically when the marker's <code>setMap(null)</code>
 * method is called.
 * @private
 */
MarkerLabel_.prototype.onRemove = function () {
    var i;
    this.labelDiv_.parentNode.removeChild(this.labelDiv_);
    this.eventDiv_.parentNode.removeChild(this.eventDiv_);

    // Remove event listeners:
    for (i = 0; i < this.listeners_.length; i++) {
        google.maps.event.removeListener(this.listeners_[i]);
    }
};

/**
 * Draws the label on the map.
 * @private
 */
MarkerLabel_.prototype.draw = function () {
    this.setContent();
    this.setTitle();
    this.setStyles();
};

/**
 * Sets the content of the label.
 * The content can be plain text or an HTML DOM node.
 * @private
 */
MarkerLabel_.prototype.setContent = function () {
    var content = this.marker_.get("labelContent");
    if (typeof content.nodeType === "undefined") {
        this.labelDiv_.innerHTML = content;
        this.eventDiv_.innerHTML = this.labelDiv_.innerHTML;
    } else {
        this.labelDiv_.innerHTML = ""; // Remove current content
        this.labelDiv_.appendChild(content);
        content = content.cloneNode(true);
        this.eventDiv_.appendChild(content);
    }
};

/**
 * Sets the content of the tool tip for the label. It is
 * always set to be the same as for the marker itself.
 * @private
 */
MarkerLabel_.prototype.setTitle = function () {
    this.eventDiv_.title = this.marker_.getTitle() || "";
};

/**
 * Sets the style of the label by setting the style sheet and applying
 * other specific styles requested.
 * @private
 */
MarkerLabel_.prototype.setStyles = function () {
    var i, labelStyle;

    // Apply style values from the style sheet defined in the labelClass parameter:
    this.labelDiv_.className = this.marker_.get("labelClass");
    this.eventDiv_.className = this.labelDiv_.className;

    // Clear existing inline style values:
    this.labelDiv_.style.cssText = "";
    this.eventDiv_.style.cssText = "";
    // Apply style values defined in the labelStyle parameter:
    labelStyle = this.marker_.get("labelStyle");
    for (i in labelStyle) {
        if (labelStyle.hasOwnProperty(i)) {
            this.labelDiv_.style[i] = labelStyle[i];
            this.eventDiv_.style[i] = labelStyle[i];
        }
    }
    this.setMandatoryStyles();
};

/**
 * Sets the mandatory styles to the DIV representing the label as well as to the
 * associated event DIV. This includes setting the DIV position, z-index, and visibility.
 * @private
 */
MarkerLabel_.prototype.setMandatoryStyles = function () {
    this.labelDiv_.style.position = "absolute";
    this.labelDiv_.style.overflow = "hidden";
    // Make sure the opacity setting causes the desired effect on MSIE:
    if (typeof this.labelDiv_.style.opacity !== "undefined" && this.labelDiv_.style.opacity !== "") {
        this.labelDiv_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")\"";
        this.labelDiv_.style.filter = "alpha(opacity=" + (this.labelDiv_.style.opacity * 100) + ")";
    }

    this.eventDiv_.style.position = this.labelDiv_.style.position;
    this.eventDiv_.style.overflow = this.labelDiv_.style.overflow;
    this.eventDiv_.style.opacity = 0.01; // Don't use 0; DIV won't be clickable on MSIE
    this.eventDiv_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(opacity=1)\"";
    this.eventDiv_.style.filter = "alpha(opacity=1)"; // For MSIE

    this.setAnchor();
    this.setPosition(); // This also updates z-index, if necessary.
    this.setVisible();
};

/**
 * Sets the anchor point of the label.
 * @private
 */
MarkerLabel_.prototype.setAnchor = function () {
    var anchor = this.marker_.get("labelAnchor");
    this.labelDiv_.style.marginLeft = -anchor.x + "px";
    this.labelDiv_.style.marginTop = -anchor.y + "px";
    this.eventDiv_.style.marginLeft = -anchor.x + "px";
    this.eventDiv_.style.marginTop = -anchor.y + "px";
};

/**
 * Sets the position of the label. The z-index is also updated, if necessary.
 * @private
 */
MarkerLabel_.prototype.setPosition = function (yOffset) {
    var position = this.getProjection().fromLatLngToDivPixel(this.marker_.getPosition());
    if (typeof yOffset === "undefined") {
        yOffset = 0;
    }
    this.labelDiv_.style.left = Math.round(position.x) + "px";
    this.labelDiv_.style.top = Math.round(position.y - yOffset) + "px";
    this.eventDiv_.style.left = this.labelDiv_.style.left;
    this.eventDiv_.style.top = this.labelDiv_.style.top;

    this.setZIndex();
};

/**
 * Sets the z-index of the label. If the marker's z-index property has not been defined, the z-index
 * of the label is set to the vertical coordinate of the label. This is in keeping with the default
 * stacking order for Google Maps: markers to the south are in front of markers to the north.
 * @private
 */
MarkerLabel_.prototype.setZIndex = function () {
    var zAdjust = (this.marker_.get("labelInBackground") ? -1 : +1);
    if (typeof this.marker_.getZIndex() === "undefined") {
        this.labelDiv_.style.zIndex = parseInt(this.labelDiv_.style.top, 10) + zAdjust;
        this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
    } else {
        this.labelDiv_.style.zIndex = this.marker_.getZIndex() + zAdjust;
        this.eventDiv_.style.zIndex = this.labelDiv_.style.zIndex;
    }
};

/**
 * Sets the visibility of the label. The label is visible only if the marker itself is
 * visible (i.e., its visible property is true) and the labelVisible property is true.
 * @private
 */
MarkerLabel_.prototype.setVisible = function () {
    if (this.marker_.get("labelVisible")) {
        this.labelDiv_.style.display = this.marker_.getVisible() ? "block" : "none";
    } else {
        this.labelDiv_.style.display = "none";
    }
    this.eventDiv_.style.display = this.labelDiv_.style.display;
};

/**
 * @name MarkerWithLabelOptions
 * @class This class represents the optional parameter passed to the {@link MarkerWithLabel} constructor.
 *  The properties available are the same as for <code>google.maps.Marker</code> with the addition
 *  of the properties listed below. To change any of these additional properties after the labeled
 *  marker has been created, call <code>google.maps.Marker.set(propertyName, propertyValue)</code>.
 *  <p>
 *  When any of these properties changes, a property changed event is fired. The names of these
 *  events are derived from the name of the property and are of the form <code>propertyname_changed</code>.
 *  For example, if the content of the label changes, a <code>labelcontent_changed</code> event
 *  is fired.
 *  <p>
 * @property {string|Node} [labelContent] The content of the label (plain text or an HTML DOM node).
 * @property {Point} [labelAnchor] By default, a label is drawn with its anchor point at (0,0) so
 *  that its top left corner is positioned at the anchor point of the associated marker. Use this
 *  property to change the anchor point of the label. For example, to center a 50px-wide label
 *  beneath a marker, specify a <code>labelAnchor</code> of <code>google.maps.Point(25, 0)</code>.
 *  (Note: x-values increase to the right and y-values increase to the top.)
 * @property {string} [labelClass] The name of the CSS class defining the styles for the label.
 *  Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>,
 *  <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and
 *  <code>marginTop</code> are ignored; these styles are for internal use only.
 * @property {Object} [labelStyle] An object literal whose properties define specific CSS
 *  style values to be applied to the label. Style values defined here override those that may
 *  be defined in the <code>labelClass</code> style sheet. If this property is changed after the
 *  label has been created, all previously set styles (except those defined in the style sheet)
 *  are removed from the label before the new style values are applied.
 *  Note that style values for <code>position</code>, <code>overflow</code>, <code>top</code>,
 *  <code>left</code>, <code>zIndex</code>, <code>display</code>, <code>marginLeft</code>, and
 *  <code>marginTop</code> are ignored; these styles are for internal use only.
 * @property {boolean} [labelInBackground] A flag indicating whether a label that overlaps its
 *  associated marker should appear in the background (i.e., in a plane below the marker).
 *  The default is <code>false</code>, which causes the label to appear in the foreground.
 * @property {boolean} [labelVisible] A flag indicating whether the label is to be visible.
 *  The default is <code>true</code>. Note that even if <code>labelVisible</code> is
 *  <code>true</code>, the label will <i>not</i> be visible unless the associated marker is also
 *  visible (i.e., unless the marker's <code>visible</code> property is <code>true</code>).
 * @property {boolean} [raiseOnDrag] A flag indicating whether the label and marker are to be
 *  raised when the marker is dragged. The default is <code>true</code>. If a draggable marker is
 *  being created and a version of Google Maps API earlier than V3.3 is being used, this property
 *  must be set to <code>false</code>.
 * @property {boolean} [optimized] A flag indicating whether rendering is to be optimized for the
 *  marker. <b>Important: The optimized rendering technique is not supported by MarkerWithLabel,
 *  so the value of this parameter is always forced to <code>false</code>.
 * @property {string} [crossImage="http://maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png"]
 *  The URL of the cross image to be displayed while dragging a marker.
 * @property {string} [handCursor="http://maps.gstatic.com/intl/en_us/mapfiles/closedhand_8_8.cur"]
 *  The URL of the cursor to be displayed while dragging a marker.
 */
/**
 * Creates a MarkerWithLabel with the options specified in {@link MarkerWithLabelOptions}.
 * @constructor
 * @param {MarkerWithLabelOptions} [opt_options] The optional parameters.
 */
function MarkerWithLabel(opt_options) {
    opt_options = opt_options || {};
    opt_options.labelContent = opt_options.labelContent || "";
    opt_options.labelAnchor = opt_options.labelAnchor || new google.maps.Point(0, 0);
    opt_options.labelClass = opt_options.labelClass || "markerLabels";
    opt_options.labelStyle = opt_options.labelStyle || {};
    opt_options.labelInBackground = opt_options.labelInBackground || false;
    if (typeof opt_options.labelVisible === "undefined") {
        opt_options.labelVisible = true;
    }
    if (typeof opt_options.raiseOnDrag === "undefined") {
        opt_options.raiseOnDrag = true;
    }
    if (typeof opt_options.clickable === "undefined") {
        opt_options.clickable = true;
    }
    if (typeof opt_options.draggable === "undefined") {
        opt_options.draggable = false;
    }
    if (typeof opt_options.optimized === "undefined") {
        opt_options.optimized = false;
    }
    opt_options.crossImage = opt_options.crossImage || "http" + (document.location.protocol === "https:" ? "s" : "") + "://maps.gstatic.com/intl/en_us/mapfiles/drag_cross_67_16.png";
    opt_options.handCursor = opt_options.handCursor || "http" + (document.location.protocol === "https:" ? "s" : "") + "://maps.gstatic.com/intl/en_us/mapfiles/closedhand_8_8.cur";
    opt_options.optimized = false; // Optimized rendering is not supported

    this.label = new MarkerLabel_(this, opt_options.crossImage, opt_options.handCursor); // Bind the label to the marker

    // Call the parent constructor. It calls Marker.setValues to initialize, so all
    // the new parameters are conveniently saved and can be accessed with get/set.
    // Marker.set triggers a property changed event (called "propertyname_changed")
    // that the marker label listens for in order to react to state changes.
    google.maps.Marker.apply(this, arguments);
}
inherits(MarkerWithLabel, google.maps.Marker);

/**
 * Overrides the standard Marker setMap function.
 * @param {Map} theMap The map to which the marker is to be added.
 * @private
 */
MarkerWithLabel.prototype.setMap = function (theMap) {

    // Call the inherited function...
    google.maps.Marker.prototype.setMap.apply(this, arguments);

    // ... then deal with the label:
    this.label.setMap(theMap);
};

google.maps.MarkerWithLabel = MarkerWithLabel;
ues to initialize, so all
    // the new parameters are conveniently saved and can be accessed with get/set.
    // Marker.set triggers a property changed event (called "propertyname_changed")
    // that the marker label listens for in order to react to state changes.
    google.maps.Marker.apply(this, arguments);
}
inherits(MarkerWithLabel, google.maps.Marker);

/**
 * Overrides the standard Marker setMap function.
 * @param {Map} theMap The map to which the marker is to be added.
 * @private
 */
MarkerWithLabel.prototype.setMap = function (theMap) {

    // Call the inherited function...
    google.maps.Marker.prototype.setMap.apply(this, arguments);

    // ... then deal with the label:
    this.label.setMap(theMap);
};

google.maps.MarkerWithLabel = MarkerWithLabel;
           

繼續閱讀