Закройте все информационные окна в Google Maps API v3
Я занят скриптом, который сделает холст google maps на моем сайте с несколькими маркерами. Я хочу, чтобы при нажатии на маркер, infowindow открывается. Я сделал это, и код на данный момент:
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
function addMarker(map, address, title) {
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title:title
});
google.maps.event.addListener(marker, 'click', function() {
var infowindow = new google.maps.InfoWindow();
infowindow.setContent('<strong>'+title + '</strong><br />' + address);
infowindow.open(map, marker);
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
addMarker(map, 'Address', 'Title');
addMarker(map, 'Address', 'Title');
это работает на 100%. Но теперь я хочу, чтобы когда одно infowindow открыто, а вы хотите открыть второе, первое автоматически закрывается. Но я не нашел способа сделать это. infowindow.закрыть(); не помогает. У кого-то есть пример или решение для этого проблема?
10 ответов:
infowindow является локальной переменной и окно не доступно во время close()
var latlng = new google.maps.LatLng(-34.397, 150.644); var infowindow = null; ... google.maps.event.addListener(marker, 'click', function() { if (infowindow) { infowindow.close(); } infowindow = new google.maps.InfoWindow(); ... }); ...
объявлять глобальные переменные:
var mapOptions; var map; var infowindow; var marker; var contentString; var image;на
intializeиспользуйте картуaddEventспособ:google.maps.event.addListener(map, 'click', function() { if (infowindow) { infowindow.close(); } });
для циклов, которые создают
infowindowsдинамически, объявить глобальная переменная
var openwindow;а потом в
addListenerвызов функции (которая находится внутри цикла):google.maps.event.addListener(marker<?php echo $id; ?>, 'click', function() { if(openwindow){ eval(openwindow).close(); } openwindow="myInfoWindow<?php echo $id; ?>"; myInfoWindow<?php echo $id; ?>.open(map, marker<?php echo $id; ?>); });
у меня был динамический цикл, который создает
infowindowsи маркеры, основанные на том, сколько было введено в CMS, поэтому я не хотел создавать новыйInfoWindow()на каждом событии нажмите и болото его вниз с запросами, если это когда-либо возникало. Вместо этого я попытался узнать, что конкретноinfowindowпеременная для каждого экземпляра будет выходить из заданного количества мест, которые у меня были, а затем запрашивать Карты, чтобы закрыть все из них, прежде чем он откроет правильный.мой массив местоположений был вызван места, поэтому PHP я настроил до фактическая инициализация карт, чтобы получить мой
infowindowимена переменных было:for($k = 0; $k < count($locations); $k++) { $infowindows[] = 'infowindow' . $k; }затем после инициализации карты и так далее, в скрипте у меня был PHP
foreachцикл создания динамических информационных окон с помощью счетчика://...javascript map initilization <?php $i=0; foreach($locations as $location) { ..//get latitudes, longitude, image, etc... echo 'var mapMarker' . $i . ' = new google.maps.Marker({ position: myLatLng' . $i . ', map: map, icon: image });'; echo 'var contentString' . $i . ' = "<h1>' . $title[$i] . '</h1><h2>' . $address[$i] . '</h2>' . $content[$i] . '";'; echo 'infowindow' . $i . ' = new google.maps.InfoWindow({ '; echo ' content: contentString' . $i . ' });'; echo 'google.maps.event.addListener(mapMarker' . $i . ', "click", function() { '; foreach($infowindows as $window) { echo $window . '.close();'; } echo 'infowindow' . $i . '.open(map,mapMarker'. $i . '); });'; $i++; } ?> ...//continue with Maps script...Итак, дело в том, что до того, как я вызвал весь скрипт карты, у меня был массив с именами, которые, как я знал, будут выведены, когда , как
infowindow0, infowindow1, infowindow2, etc...затем на
clickсобытие для каждого маркера,foreachцикл проходит и говорит закрыть все из них, прежде чем выполнить следующий шаг их открытия. Получается примерно так:google.maps.event.addListener(mapMarker0, "click", function() { infowindow0.close(); infowindow1.close(); infowindow2.close(); infowindow0.open(map,mapMarker0); }просто другой способ делать вещи, я полагаю... но я надеюсь, что это кому-то поможет.
у меня что-то вроде следующего
function initMap() { //...create new map here var infowindow; $('.business').each(function(el){ //...get lat/lng var position = new google.maps.LatLng(lat, lng); var content = "contents go here"; var title = "titleText"; var openWindowFn; var closure = function(content, position){. openWindowFn = function() { if (infowindow) { infowindow.close(); } infowindow = new google.maps.InfoWindow({ position:position, content:content }); infowindow.open(map, marker); } }(content, position); var marker = new google.maps.Marker({ position:position, map:map, title:title. }); google.maps.event.addListener(marker, 'click', openWindowFn); } }в моем понимании, использование такого закрытия позволяет захватывать переменные и их значения во время объявления функции, а не полагаться на глобальные переменные. Так что когда
openWindowFnвызывается позже, на первом маркере например,contentиpositionпеременные имеют значения, которые они делали во время первой итерации в
Я призываю вас, чтобы попробовать системы gomap плагин jQuery при работе с картами Google. Для такого рода ситуации вы можете установить hideByClick в true при создании маркеров:
$(function() { $("#map").goMap({ markers: [{ latitude: 56.948813, longitude: 24.704004, html: { content: 'Click to marker', popup:true } },{ latitude: 54.948813, longitude: 21.704004, html: 'Hello!' }], hideByClick: true }); });Это всего лишь один пример, он имеет много функций, чтобы предложить, как группировка маркеров и манипулирование информационными окнами.
при работе с кластерами маркеров этот работал для меня.
var infowindow = null; google.maps.event.addListener(marker, "click", function () { if (infowindow) { infowindow.close(); } var markerMap = this.getMap(); infowindow = this.info; this.info.open(markerMap, this); });
Я был час с головной болью, пытаясь закрыть infoWindow! Мой последний (и рабочий) вариант закрывал infoWindow с помощью SetTimeout (несколько секунд) Это не самый лучший способ... но это работает легко
marker.addListener('click', function() { infowindow.setContent(html); infowindow.open(map, this); setTimeout(function(){ infowindow.close(); },5000); });
У меня есть пример моего кода, который может помочь. Я установил только один объект infowindow в глобальном масштабе. Затем используйте setContent () для установки содержимого перед его отображением.
let map; let infowindow; let dataArr = [ { pos:{lat: -34.397, lng: 150.644}, content: 'First marker' }, { pos:{lat: -34.340, lng: 150.415}, content: 'Second marker' } ]; function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); // Set infowindow object to global varible infowindow = new google.maps.InfoWindow(); loadMarker(); } function loadMarker(){ dataArr.forEach((obj, i)=>{ let marker = new google.maps.Marker({ position: obj.pos, map: map }); marker.addListener('click', function() { infowindow.close() infowindow.setContent(`<div> ${obj.content} </div>`) infowindow.open(map, marker); }); }) }
Comments