2015-02-18 11 views
5

Sto utilizzando l'API di Google Maps e ho qualche problema su InfoWindow.Google Maps La larghezza di InfoWindow viene sovrascritta anche se impostata correttamente

Ecco un riassunto:

  • Sto caricando il contenuto del InfoWindow quando l'utente fa clic su un marcatore
  • Il contenuto è una vista parziale, caricati grazie ad un Ajax chiamano
  • In. fatto callback, chiamo un metodo asincrono che inserirà i dati nel contenuto di InfoWindow. Devo farlo perché voglio che il contenuto principale di InfoWindow venga visualizzato immediatamente, mentre questa informazione "bonus" potrebbe essere visualizzata dopo qualche decimo di secondo.

Questo funziona perfettamente; ma ho una striscia bianca sulla destra del mio InfoWindow non riesco a rimuovere (vedi foto qui sotto)

Tuttavia, il carico di contenuti che è incluso in un <div> con un fisso width:

<div id="div-main-infoWindow"> 
    <!-- All my content --> 
</div> 

e nel mio CSS, ho scritto:

#div-main-infoWindow { 
    width:342px !important; 
} 


il caricamento del InfoWindow, con maggiori dettagli, assomiglia a questo:

$.ajax({ 
      url   : "/my-url", 
      async  : false, 
      contentType : "application/json; charset=utf-8", 
      dataType : "json", 
      type  : "POST", 
      data  : JSON.stringify(myModel) 
     }).done(function(response) { 

      MarkerContent = response.Content; //The HTML content to display 

      MyAsyncMethod().then(function(response) { 
       //do some formatting with response 
       return result; //result is just a small HTML string 
      }).done(function(result1, result2) { 
       //do some formatting with result1 and result2 
       $("#myNode").html(/*formatted result*/); 
      }) 

      //info is a global variable defined as new google.maps.InfoWindow() 
      info.setOptions({ 
       content: MarkerContent, 
       maxWidth: 342 //To be sure 
      }); 

      info.open(map, marker); 
     }); 
}); 

Il contenuto è perfettamente OK, il problema è tutto di questa striscia bianca.

Guardando la mia console del browser (ho riprodotto in tutti i browser), posso vedere questo:

IW

Come si può vedere, il mio <div> contenente tutti i miei dati caricati dalla mia chiamata AJAX va bene con le buone dimensioni (rettangolo verde, corrispondente alla zona grigia dello screenshot), MA le div precedenti (dalla stessa API di Google, nei rettangoli rossi) hanno una dimensione maggiore, da cui il problema è.

L'unico modo che ho trovato è in esecuzione questo script jQuery modificare la InfoWindow struttura interna:

$(".gm-style-iw").next().remove(); 
$(".gm-style-iw").prev().children().last().width(342); 
$(".gm-style-iw").prev().children(":nth-child(2)").width(342); 

$(".gm-style-iw").width(342); 
$(".gm-style-iw").children().first().css("overflow", "hidden"); 
$(".gm-style-iw").children().first().children().first().css("overflow", "hidden"); 
$(".gm-style-iw").parent().width(342); 

Nota: gm-style-iw è il nome della classe data dal Google del div che contiene tutti i contenuti del InfoWindow, quello si è fermato sullo screenshot qui sopra. Ho anche aggiungere questa regola nel mio CSS:

.gm-style-iw { 
    width: 342px !important; //also tried with 100% !important, not better 
} 

Funziona nella console, tuttavia, non ha alcun effetto quando scritto nel codice stesso, nel .done richiamata, o in caso in cui le domready Google Maps ..
Tuttavia, in questo caso tardo, se incapsulare lo script jQuery sopra in un setTimeout(), funziona !! Ho commentato il metodo asincrono, quindi non è questo che è colpevole, ma sembra che domready sia eseguito mentre il 100% di InfoWindow non è ancora visualizzato - che è contrary to the doc.

Ho anche provato a spostare il mio info.setOptions all'esterno del .done e richiamarlo dopo, senza effetto.

Quindi, come posso visualizzare una finestra di dialogo "normale" senza questa striscia bianca sulla destra?
Non voglio implementareo altra libreria personalizzata di InfoWindow. È un progetto personale e voglio capire perché e dove si trova il problema. E, naturalmente, trova una soluzione.

Grazie per il vostro aiuto!

+0

Funziona con la mia sola volta, una al secondo scatto dello stesso o di un altro marker, si gies i valaues di default, il 'custom-IW' viene rimosso dopo il secondo clic – user1392021

risposta

10

È un po 'più complesso di quanto si pensi.

solo alcune cose:

  • avete notato che v'è una stretta pulsante? Anche quando si rimuove il pulsante spazio ci sarà, perché l'API calcola la dimensione degli altri nodi sulla base di questo spazio
  • la punta deve essere al centro
  • ci sono ulteriori contenitori per i bordi arrotondati ed ombre
  • la dimensione del infowindow sarà calcolata in modo che si inserisca nella finestra
  • il contenuto deve essere scorrevole quando necessario
  • posizione del infowindow deve essere impostato (quindi è richiesto per calcolare l'altezza esatta della infowindow)

Sostanzialmente: tutte queste cose richiedono il calcolo di dimensioni e posizioni esatte, la maggior parte dei nodi in infowindow sono posizionati in modo assoluto, è piuttosto una tecnica come quella che verrà utilizzata in DTP di quanto si utilizzerebbe in un documento HTML.

Inoltre: InfoWindows verrà modificato molto spesso per correggere i bug, una soluzione che funziona oggi potrebbe essere interrotta domani.

Tuttavia, un approccio che attualmente funziona per me:

  1. impostare il maxWidth del infowindow alla larghezza desiderata - 51 (sarebbe 291 in questo caso)
  2. Non è possibile applicare !important -rules via $.css, quindi deve essere fatto direttamente tramite un foglio di stile. Per essere in grado di accedere a tutti gli elementi di impostare una nuova classe per la radice-nodo del infowindow (si noti che ci possono essere infoWindows che non si possono controllare, ad esempio, i POI):

    google.maps.event.addListener(infowindow,'domready',function(){ 
        $('#div-main-infoWindow')//the root of the content 
        .closest('.gm-style-iw') 
        .parent().addClass('custom-iw'); 
    }); 
    
  3. CSS:

.custom-iw .gm-style-iw { 
     top:15px !important; 
     left:0 !important; 
     border-radius:2px; 
    } 
    .custom-iw>div:first-child>div:nth-child(2) { 
     display:none; 
    } 
    /** the shadow **/ 
    .custom-iw>div:first-child>div:last-child { 
     left:0 !important; 
     top:0px; 
     box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 6px; 
     z-index:-1 !important; 
    } 

    .custom-iw .gm-style-iw, 
    .custom-iw .gm-style-iw>div, 
    .custom-iw .gm-style-iw>div>div { 
     width:100% !important; 
     max-width:100% !important; 
    } 
    /** set here the width **/ 
    .custom-iw, 
    .custom-iw>div:first-child>div:last-child { 
     width:342px !important; 
    } 


    /** set here the desired background-color **/ 
    #div-main-infoWindow, 
    .custom-iw>div:first-child>div:nth-child(n-1)>div>div, 
    .custom-iw>div>div:last-child, 
    .custom-iw .gm-style-iw, 
    .custom-iw .gm-style-iw>div, 
    .custom-iw .gm-style-iw>div>div { 
     background-color:orange !important; 
    } 

    /** close-button(note that there may be a scrollbar) **/ 
    .custom-iw>div:last-child { 
     top:1px !important; 
     right:0 !important; 
    } 

    /** padding of the content **/ 
    #div-main-infoWindow { 
     padding:6px; 
    } 

Demo (domani, come ho detto, può essere rotto): http://jsfiddle.net/doktormolle/k57qojq7/

+0

Man, sei fantastico! Grazie per la spiegazione E il codice :-) Solo una cosa, non capisco perché dici di impostare 'maxwidth' su 342 - 51; mentre lo imposti a 342 nel tuo codice? Al momento, il mio '.gm-style-iw' ha una' larghezza: 100% 'nel mio CSS ed è OK. È meglio impostare 'max-width' a 291px? – AlexB

+0

Intendo l'opzione 'maxWidth' di InfoWindow (non il CSS), potresti vederlo nel codice del violino. –

+0

342 o 291 dato che 'max-width' produce sempre lo stesso (buono) risultato, è strano ... Comunque, grazie mille per il tuo aiuto – AlexB

0

po 'tardi per la festa qui, ma dopo aver cercato per secoli ad un credo che la stessa cosa dell'OP sia un pensiero che mi è venuto in mente. Sembrava che la larghezza venisse impostata dall'elemento genitore di .gm-style-iw quindi ho semplicemente impostato la larghezza degli elementi genitore su auto usando jQuery e hey presto! Quindi ecco il mio codice nella speranza che possa aiutare qualcuno in futuro.

JS

$('.gm-style-iw').parent().css('width', 'auto'); 

CSS

.gm-style-iw { 
width: auto !important; 
top: 0 !important; 
left: 0 !important; 
} 
Problemi correlati