43

I'm making a mobile web app.

Part of the app drops several markers, which can be clicked to open info windows. It irritates me that these do not go away if you continue using the map without acknowledging them, as in the iOS maps app.

Is there a way to set it so that if the user clicks the underlying map, all open info windows are closed?

temporary_user_name
  • 35,956
  • 47
  • 141
  • 220

6 Answers6

70

Try this:

google.maps.event.addListener(map, "click", function(event) {
    infowindow.close();
});

It is quite simple an should work as well.

Marcus Rommel
  • 1,266
  • 1
  • 12
  • 17
  • 2
    It worth to say that this code needs to be inside the marker event listener function `google.maps.event.addListener(marker, 'click', function() {`, coz i spent sometime trying to make it work without knowing it should be there. Thanks. – tinyCoder Mar 09 '18 at 19:54
  • 1
    @tinyCoder Not necessarily. It could be that the `infowindow` variable is local to the marker click handler in your code, but that's not a given. – ebbishop Nov 05 '20 at 17:42
46

add listener to map's click event and close infoboxes in its handler

google.maps.event.addListener(map, "click", function(event) {
    for (var i = 0; i < ibArray.length; i++ ) {  //I assume you have your infoboxes in some array
         ibArray[i].close();
    }
});

I do that on typical websites, but don't see any reason it wouldn't work on mobile

slawekwin
  • 6,270
  • 1
  • 44
  • 57
  • 4
    Also map.addListener("click", function(event) {... works – Nigel Johnson Dec 30 '16 at 11:08
  • This answer is not the best solution, check out Marcus Rommel's answer. You don't create multiple infoWindows, you create one and then populate it based on which marker you click, so you don't need to use some loop to close them all. There's a way easier solution. – s1h4d0w Dec 04 '18 at 16:17
8
google.maps.event.addListener(marker, 'click', function() {
    if(!marker.open){
        infoWindow.open(map,marker);
        marker.open = true;
    }
    else{
        infoWindow.close();
        marker.open = false;
    }
    google.maps.event.addListener(map, 'click', function() {
        infoWindow.close();
        marker.open = false;
    });
});

Works perfectly

Komal12
  • 3,340
  • 4
  • 16
  • 25
user1724001
  • 119
  • 1
  • 2
  • 1
    This answer bind a listener everytime you open the marker. Add some console.log() and you'll see that it is fired more and more... – kaiser Nov 20 '18 at 03:10
1

I noticed some problems with the other answers.

Answer of Marcus Rommel and slawekwin:

When a marker is clicked, the map click event is fired afterwards. So when marker click opens the window, the propagation of the click event to map will close the window again immediately.

Answer of user1724001:

Creating a listener everytime a marker is clicked is also not a good idea. This pollutes the memory.

Therefore i just want to add some additional information to the first answers, to stop event propagation to the map. The Windows will then only be closed, if no marker is clicked.

marker.addListener("click", function(event) {
    // open your window here
    event.stopPropagation(); // this prevents propagation of marker click to map click
});

map.addListener("click", function() {
    // close your window
});
kaiser
  • 940
  • 1
  • 10
  • 25
  • This does not work anymore. `marker.addListener("click"` doesn't get an `event` parameter anymore. The `stopPropagation` is not needed anymore either, google maps does it by default. – Sergiu Paraschiv Jan 21 '19 at 15:12
  • Actually Marcus Rommel solution does work. He adds a listener to the 'map' to close the infowindow. The listener to open the infowindow is on the 'marker'. – y2knoproblem May 09 '19 at 12:41
1

I have better solution for all senario.

Try this: JSFiddle

const infoWindow = new google.maps.InfoWindow();

function init() {
    const map = new google.maps.Map(document.getElementById('map'), {
        zoom: 6,
        center: new google.maps.LatLng(39.9646, 30.8259),
        mapTypeId: google.maps.MapTypeId.TERRAIN
    });

    map.addListener('click', () => {
        if (infoWindow) {
            infoWindow.close();
        }
    });

    const istanbulMark = new google.maps.Marker({
        position: new google.maps.LatLng(41.0876, 28.9288),
        map: map,
        label: 'I'
    });

    istanbulMark.addListener('click', () => {
        infoWindow.setContent(`
            <h1>Hi mate</h1>
            <hr>
            <p>Welcome to İstanbul!</p>
          `)
        infoWindow.open(map, istanbulMark);
    });

    const ankaraMark = new google.maps.Marker({
        position: new google.maps.LatLng(39.9162, 32.8437),
        map: map,
        label: 'A'
    });

    ankaraMark.addListener('click', () => {
        infoWindow.setContent(`
            <h1>Hi mate</h1>
            <hr>
            <p>Welcome to Ankara!</p>
          `)
        infoWindow.open(map, ankaraMark);
    });
}

google.maps.event.addDomListener(window, 'load', init);
 html, body, #map {
      height: 100%;
      margin: 0px;
      padding: 0px
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true">
  </script>
</head>
<body>
  <div id="map"></div>
</body>
</html>
Necip Sunmaz
  • 1,546
  • 17
  • 22
0

Another solution that works for me : Create an array of infoWindows and close every active window when click on another window :

marker.addListener('click', () => {
this.mapInfoWindows.forEach(element => {
  element.close();
});
infoWindow.open(this.map.googleMap, marker);});