2010-12-27 16 views
57

Sono occupato con uno script che creerà una tela google maps sul mio sito Web, con più marcatori. Voglio che quando fai clic su un marker, si apra una finestra di apertura. L'ho fatto e il codice è al momento:Chiudi tutte le infowindows nell'API di Google Maps v3

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'); 

Questo funziona al 100%. Ma ora lo voglio quando una finestra aperta è aperta, e vuoi aprire la seconda, la prima si chiude automaticamente. Ma non ho trovato un modo per farlo. infowindow.close(); non aiuterà Qualcuno ha un esempio o una soluzione a questo problema?

risposta

123

infowindow è variabile locale e la finestra non è disponibile al momento della stretta()

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(); 
    ... 
}); 
... 
+7

Grazie per questo. Ho cambiato il mio codice dall'avere più InfoWindows per avere solo uno che viene chiuso/aperto su ogni marker.click. Funziona come un fascino. – William

+0

@William, hai qualche possibilità di pubblicare un frammento di codice per quello che hai fatto e condividerlo qui? – Carl

+1

@Carl vedere la modifica sopra. Speriamo che questo aiuti. – William

12

dichiarare le variabili globali:

var mapOptions; 
var map; 
var infowindow; 
var marker; 
var contentString; 
var image; 

In intialize utilizzare addEvent metodo della mappa:

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

Ho avuto un ciclo dinamico che stava creando il infowindows e marcatori in base a quanti sono stati inseriti nel CMS, quindi non volevo creare un nuovo InfoWindow() su ogni evento e fare clic su di esso con le richieste, se mai si fosse verificato. Invece, ho cercato di sapere quale variabile specifica per infowindow per ogni istanza stava per essere fuori dalla quantità impostata di posizioni che avevo, quindi chiedi a Maps di chiuderle tutte prima di aprire quella corretta.

La mia serie di posizioni è stato chiamato località, in modo che il PHP ho istituito prima le mappe attuali initilization per ottenere i miei infowindow nomi delle variabili era:

for($k = 0; $k < count($locations); $k++) { 
     $infowindows[] = 'infowindow' . $k; 
} 

Poi, dopo initialzing la mappa e così via , nella sceneggiatura ho avuto un PHP foreach ciclo creare le finestre informazioni dinamiche usando un contatore:

//...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... 

Quindi, il punto è, prima che ho chiamato l'intero script carta, ho avuto una matrice con i nomi che conoscevo stavano per essere emesso quando un InfoWindow() è stato creato, come infowindow0, infowindow1, infowindow2, etc...

Poi, l'evento click per ogni marcatore , il ciclo foreach passa e dice di chiuderli tutti prima di proseguire con il prossimo passaggio di apertura. Si scopre simile a questo:

google.maps.event.addListener(mapMarker0, "click", function() { 
    infowindow0.close(); 
    infowindow1.close(); 
    infowindow2.close(); 
    infowindow0.open(map,mapMarker0); 
} 

solo un modo diverso di fare le cose suppongo ... ma spero che aiuta qualcuno.

+2

questo è un codice orribile per mantenere imo .. perché non si stampa un array json con php e feed che ad un certo codice javascript –

5

Per i cicli che crea infowindows dinamicamente, dichiarare una variabile globale

var openwindow;

e poi nella chiamata addListener funzione (che è all'interno del ciclo):

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; ?>); 
}); 
+0

Puoi spiegare lo scopo di usare eval qui? – AnixPasBesoin

+0

'openwindow' è una stringa se non usiamo eval l'istruzione verrà eseguita come' openwindow.close() 'invece di' myInfoWindow1.close() '. Controlla i messaggi di errore che vedi qui: https://jsfiddle.net/ts3z6nw6/1/ – Binod

+0

Le mie infowindows sono state aggiunte tramite JS - Ho usato lo stesso approccio, dichiarando openwindow al di fuori del mio forEach() che crea i marcatori con windows. Nel mio codice non ho bisogno di usare eval come openwindow è già l'oggetto openwindow. – GuruBob

0

ho qualcosa come il seguente

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); 
    } 
} 

Nella mia comprensione, utilizzando una chiusura del genere che permette la cattura di variabili e il loro valore al momento della dichiarazione di funzione, piuttosto che basarsi su variabili globali. Così, quando openWindowFn è chiamato in seguito, sul primo marcatore per esempio, la variabile content e position hanno i valori che hanno fatto durante la prima iterazione nella funzione each().

Non sono veramente sicuro di come openWindowFn abbia infowindow nel suo ambito. Inoltre, non sono sicuro di fare le cose per bene, ma funziona, anche con più mappe su una pagina (ogni mappa ha una finestra aperta).

Se qualcuno ha intuizioni, si prega di lasciare un commento.

0

vi incoraggio a provare goMap plugin jQuery quando si lavora con Google Maps. Per questo tipo di situazione è possibile impostare hideByClick su true durante la creazione di marcatori:

$(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 
    }); 
}); 

Questo è solo un esempio, ma ha molte caratteristiche da offrire, come il raggruppamento marcatori e manipolare finestre informative.

0

Si dovrebbe avere a fare clic mappa - $('#map-selector').click();

0

Quando si tratta di cluster marcatore questo ha lavorato per me.

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); 


    }); 
0

Sono stato un'ora con il mal di testa cercando di chiudere l'informazione Finestra! La mia ultima opzione (e di lavoro) è stato chiudendo l'infowindow con un SetTimeout (pochi secondi) Non è il modo migliore ... ma funziona easely

marker.addListener('click', function() { 
    infowindow.setContent(html); 
    infowindow.open(map, this); 

    setTimeout(function(){ 
     infowindow.close(); 
    },5000); 

}); 
0

ho avere un campione del mio codice che forse può aiutare. Avevo impostato solo un oggetto infowindow a livello globale. Quindi utilizzare setContent() per impostare il contenuto prima di mostrarlo.

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); 
     }); 
    }) 
    }