Закройте все информационные окна в Google Maps API v3
Я занят сценарием, который создаст на моем веб-сайте холст Google Maps с несколькими маркерами. Я хочу, чтобы при нажатии на маркер открывалось информационное окно. Я сделал это, и код на данный момент:
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.close(); не поможет Есть ли у кого-нибудь пример или решение этой проблемы?
12 ответов
infowindow является локальной переменной, а окно недоступно во время закрытия ()
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; ?>);
});
Напишите эту строку ниже после начала тега скрипта.
previous_Window=null;
Будет работать на все 100%. используя этот код
radius= circle.getRadius()/1000;
radius_mile= circle.getRadius()/1609.344;
newRadious = 'This Circle Radius Covers Approx ' + radius.toFixed(1) + ' Km'+' <br> This circle Radius Covers Approx '+ radius_mile.toFixed(1)+ 'Miles';
var infoWindow= new google.maps.InfoWindow({
content: newRadious
});
infoWindow.setContent(newRadious)
infoWindow.setPosition(circle.getCenter());
if (previous_Window)
previous_Window.close();
infoWindow.open(map);
previous_Window=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);
});
})
}
У меня был динамический цикл, который создавал 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...
Итак, суть в том, что до того, как я вызвал весь скрипт карты, у меня был массив с именами, которые, как я знал, должны были быть выведены, когда InfoWindow()
был создан, как infowindow0, infowindow1, infowindow2, etc...
Затем на click
событие для каждого маркера, foreach
цикл проходит и говорит закрыть все из них, прежде чем выполнить следующий шаг их открытия. Получается так:
google.maps.event.addListener(mapMarker0, "click", function() {
infowindow0.close();
infowindow1.close();
infowindow2.close();
infowindow0.open(map,mapMarker0);
}
Я полагаю, просто другой способ делать вещи, но я надеюсь, что это кому-то поможет.
Если у вас есть несколько маркеров, вы можете использовать это простое решение, чтобы закрыть ранее открытый маркер при нажатии на новый маркер:
var infowindow = new google.maps.InfoWindow({
maxWidth: (window.innerWidth - 160),
content: content
});
marker.infowindow = infowindow;
var openInfoWindow = '';
marker.addListener('click', function (map, marker) {
if (openInfoWindow) {
openInfoWindow.close();
}
openInfoWindow = this.infowindow;
this.infowindow.open(map, this);
});
При работе с кластерами маркеров этот работал для меня.
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);
});
У меня есть что-то вроде следующего
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
переменная имеет значения, которые они сделали во время первой итерации в each()
функция.
Я не совсем уверен, как openWindowFn
имеет infowindow
в своей сфере. Я также не уверен, что все делаю правильно, но это работает, даже с несколькими картами на одной странице (каждая карта получает одно открытое информационное окно).
Если у кого-то есть идеи, пожалуйста, прокомментируйте.
Я был час с головной болью, пытаясь закрыть окно информации! Мой последний (и работающий) вариант - закрывать информационное окно с помощью SetTimeout (несколько секунд). Это не лучший способ... но он работает легко
marker.addListener('click', function() {
infowindow.setContent(html);
infowindow.open(map, this);
setTimeout(function(){
infowindow.close();
},5000);
});
Вы должны нажать на свою карту - $('#map-selector').click();
Я рекомендую вам попробовать плагин goMap jQuery при работе с Google Maps. Для такой ситуации вы можете установить значение true для HideByClick при создании маркеров:
$(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
});
});
Это только один пример, он имеет много функций, таких как группировка маркеров и управление информационными окнами.