2015-05-27 45 views
0

在下面的Google地圖JS代碼中,「this.activeInfoWindow.close()」語句無法按預期工作。我想我在這裏錯過了一些重要的範圍原則。有一個更好的方法嗎?谷歌地圖JS代碼 - 「this.activeInfoWindow.close()」 - scope&this

我想要學習更好的命名空間和範圍界定以及面向對象技術。

enter image description here

var data = { 
 
     "cities": [{ 
 
     "cityCntrLat": "45.49463", 
 
     "cityCntrLng": "-73.57819", 
 
     "censusName": "MONTREAL" 
 
     }, { 
 

 
     "cityCntrLat": "43.65674", 
 
     "cityCntrLng": "-79.39819", 
 
     "censusName": "TORONTO" 
 
     }, { 
 
     "cityCntrLat": "46.80807", 
 
     "cityCntrLng": "-71.21964", 
 
     "censusName": "QUEBEC" 
 
     }] 
 
    }; 
 

 

 
    $(document).ready(function() { 
 

 
     var myApplication = { 
 

 
     // variable to hold a map 
 
     map: undefined, 
 

 
     // variable to hold current active InfoWindow 
 
     activeInfoWindow: undefined, 
 

 
     // arrays to hold copies of the cities markers 
 
     gmarkers_cities: [], 
 

 
     // ------------------------------------------------------------------------------- // 
 
     // initialize function  
 
     // ------------------------------------------------------------------------------- // 
 
     initialize: function() { 
 

 
      // map options - lots of options available here 
 
      var mapOptions = { 
 
      zoom: 5, 
 
      draggable: true, 
 
      center: new google.maps.LatLng(45.64378, -73.50497), 
 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
 
      }; 
 

 
      // create map in div called map-canvas using map options defined above 
 
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 
 

 
      var markerData = data.cities 
 
      for (var i = 0; i < markerData.length; i++) { 
 
      var myMarker = new google.maps.LatLng(markerData[i]['cityCntrLat'], markerData[i]['cityCntrLng']); 
 
      var myArray = {}; 
 
      myArray = { 
 
       "available": markerData[i]['available'] 
 
      }; 
 

 
      this.fnPlaceMarkers(myArray, myMarker, markerData[i]['censusName'], "red"); 
 

 
      }; // end for 
 

 
     }, 
 

 
     // ------------------------------------------------------------------------------- // 
 
     // create markers on the map 
 
     // ------------------------------------------------------------------------------- //  
 
     fnPlaceMarkers: function(myArray, myLocation, myCityName, fillColour) { 
 

 
      // create SVG icon that looks like a flag 
 
      // The lowercase 'm' is "relative" moveto 
 
      // the lowercase 'z' closes the path 
 
      // more on SVG path command: http://www.w3.org/TR/SVG/paths.html 
 

 
      var myIcon = { 
 
      path: 'M 0,0, 0,-40, 20,-30 , 0,-20, z', 
 
      fillColor: fillColour, 
 
      fillOpacity: 0.7, 
 
      scale: 1, 
 
      strokeColor: 'black', 
 
      strokeWeight: 2 
 
      }; 
 

 
      // clone myIcon (not sure if there is better way to do this?) 
 
      var myOtherIcon = jQuery.extend({}, myIcon); 
 

 
      myOtherIcon.fillColor = "blue"; 
 

 
      // create marker and put it on map 
 
      var marker = new google.maps.Marker({ 
 
      position: myLocation, 
 
      icon: myIcon, 
 
      map: map 
 
      }); 
 

 
      // create an InfoWindow 
 
      var infoWnd = new google.maps.InfoWindow(); 
 

 
      // add content to your InfoWindow 
 
      infoWnd.setContent('<div class="scrollFix">' + 'Welcome to ' + myCityName + '</div>'); 
 

 
      // add listener on InfoWindow - close last infoWindow before opening new one 
 
      google.maps.event.addListener(marker, 'click', function() { 
 

 
      // Close active window if exists         
 
      // WHY DOES THIS NOT WORK?? 
 
      if (typeof this.activeInfoWindow != 'undefined') { 
 
       this.activeInfoWindow.close(); 
 
      }; 
 
      console.log(typeof this.activeInfoWindow); 
 

 
      // Open InfoWindow 
 
      infoWnd.open(map, marker); 
 

 
      // Store new open InfoWindow in global variable 
 
      this.activeInfoWindow = infoWnd; 
 
      //console.log(this.activeInfoWindow); 
 
      }); 
 

 
      // keep extra copy of marker info 
 
      marker.available = myArray['available']; 
 
      this.gmarkers_cities.push(marker); 
 
     } 
 

 

 
     }; 
 
     myApplication.initialize(); 
 

 
    }); // end jquery
#map-canvas { 
 
    height: 350px; 
 
    width: 600px; 
 
} 
 
table { 
 
    border-collapse: collapse; 
 
} 
 
td { 
 
    border: 1px solid #B0B0B0; 
 
    padding: 5px; 
 
    background-color: #F8F8F8; 
 
}
<html> 
 
<script src="http://maps.googleapis.com/maps/api/js" type="text/javascript"></script> 
 
<!-- <script src="../jquery/jquery.js" type="text/javascript"></script> --> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> 
 
<!-- <script src="data.json" type="text/javascript"></script>   --> 
 

 
<table> 
 
    <tr> 
 
    <td> 
 
     <div id="map-canvas"></div> 
 
    </td> 
 

 
    </tr> 
 
</table>

+0

你說的 「不能按預期工作」 是什麼意思?你期望它做什麼?如果您試圖一次只打開一個infowindow,則只能創建一個。 – geocodezip

回答

2

使用 「這」 一個函數內不返回你的主要對象。我通過刪除this.activeInfoWindow並將其更改爲myApplication.activeInfoWindow來更改您的代碼,現在它按預期工作。

var data = { 
 
    "cities": [{ 
 
    "cityCntrLat": "45.49463", 
 
    "cityCntrLng": "-73.57819", 
 
    "censusName": "MONTREAL" 
 
    }, { 
 

 
    "cityCntrLat": "43.65674", 
 
    "cityCntrLng": "-79.39819", 
 
    "censusName": "TORONTO" 
 
    }, { 
 
    "cityCntrLat": "46.80807", 
 
    "cityCntrLng": "-71.21964", 
 
    "censusName": "QUEBEC" 
 
    }] 
 
}; 
 

 

 
$(document).ready(function() { 
 

 
    var myApplication = { 
 

 
    // variable to hold a map 
 
    map: undefined, 
 

 
    // variable to hold current active InfoWindow 
 
    activeInfoWindow: undefined, 
 

 
    // arrays to hold copies of the cities markers 
 
    gmarkers_cities: [], 
 

 
    // ------------------------------------------------------------------------------- // 
 
    // initialize function  
 
    // ------------------------------------------------------------------------------- // 
 
    initialize: function() { 
 

 
     // map options - lots of options available here 
 
     var mapOptions = { 
 
     zoom: 5, 
 
     draggable: true, 
 
     center: new google.maps.LatLng(45.64378, -73.50497), 
 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
 
     }; 
 

 
     // create map in div called map-canvas using map options defined above 
 
     map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); 
 

 
     var markerData = data.cities 
 
     for (var i = 0; i < markerData.length; i++) { 
 
     var myMarker = new google.maps.LatLng(markerData[i]['cityCntrLat'], markerData[i]['cityCntrLng']); 
 
     var myArray = {}; 
 
     myArray = { 
 
      "available": markerData[i]['available'] 
 
     }; 
 

 
     this.fnPlaceMarkers(myArray, myMarker, markerData[i]['censusName'], "red"); 
 

 
     }; // end for 
 

 
    }, 
 

 
    // ------------------------------------------------------------------------------- // 
 
    // create markers on the map 
 
    // ------------------------------------------------------------------------------- //  
 

 
    fnPlaceMarkers: function(myArray, myLocation, myCityName, fillColour) { 
 

 
     // create SVG icon that looks like a flag 
 
     // The lowercase 'm' is "relative" moveto 
 
     // the lowercase 'z' closes the path 
 
     // more on SVG path command: http://www.w3.org/TR/SVG/paths.html 
 

 
     var myIcon = { 
 
     path: 'M 0,0, 0,-40, 20,-30 , 0,-20, z', 
 
     fillColor: fillColour, 
 
     fillOpacity: 0.7, 
 
     scale: 1, 
 
     strokeColor: 'black', 
 
     strokeWeight: 2 
 
     }; 
 

 
     // clone myIcon (not sure if there is better way to do this?) 
 
     var myOtherIcon = jQuery.extend({}, myIcon); 
 

 
     myOtherIcon.fillColor = "blue"; 
 

 
     // create marker and put it on map 
 
     var marker = new google.maps.Marker({ 
 
     position: myLocation, 
 
     icon: myIcon, 
 
     map: map 
 
     }); 
 

 
     // create an InfoWindow 
 
     var infoWnd = new google.maps.InfoWindow(); 
 

 
     // add content to your InfoWindow 
 
     infoWnd.setContent('<div class="scrollFix">' + 'Welcome to ' + myCityName + '</div>'); 
 

 
     // add listener on InfoWindow - close last infoWindow before opening new one 
 
     google.maps.event.addListener(marker, 'click', function() { 
 

 
     // Close active window if exists         
 
     // WHY DOES THIS NOT WORK?? 
 
     if (typeof myApplication.activeInfoWindow != 'undefined') { 
 
      myApplication.activeInfoWindow.close(); 
 
     }; 
 

 

 
     // Open InfoWindow 
 
     infoWnd.open(map, marker); 
 

 
     // Store new open InfoWindow in global variable 
 
     myApplication.activeInfoWindow = infoWnd; 
 
     //console.log(this.activeInfoWindow); 
 
     }); 
 

 
     // keep extra copy of marker info 
 
     marker.available = myArray['available']; 
 
     this.gmarkers_cities.push(marker); 
 
    } 
 

 

 
    }; 
 
    myApplication.initialize(); 
 

 
}); // end jquery
#map-canvas { 
 
    height: 350px; 
 
    width: 600px; 
 
} 
 
table { 
 
    border-collapse: collapse; 
 
} 
 
td { 
 
    border: 1px solid #B0B0B0; 
 
    padding: 5px; 
 
    background-color: #F8F8F8; 
 
}
<html> 
 
<script src="http://maps.googleapis.com/maps/api/js" type="text/javascript"></script> 
 
<!-- <script src="../jquery/jquery.js" type="text/javascript"></script> --> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> 
 
<!-- <script src="data.json" type="text/javascript"></script>   --> 
 

 

 
<table> 
 
    <tr> 
 
    <td> 
 
     <div id="map-canvas"></div> 
 
    </td> 
 
    </tr> 
 
</table>

+0

謝謝湯姆!這很好用!但是,爲什麼myApplication.activeInfoWindow工作,但不是this.activeInfoWindow。而myApplication.gmarkers_cities和this.gmarkers_cities似乎是相同的。 –

+0

this.gmarkers_cities.push(marker)(我想你的意思是這個)不存在於點擊監聽器中。您在偵聽器中獲得的「this」對象是發生點擊的對象。在這種情況下,它是地圖對象而不是你的myApplication對象。 –

+0

再次感謝。任何其他改進建議?我正在嘗試使用範圍和OO代碼來使應用程序更加模塊化,並避免維護許多全局變量。 –