Styling Google Maps InfoWindow


116

J'ai essayé de styliser mon Google Maps InfoWindow, mais la documentation est très limitée sur ce sujet. Comment coiffez-vous un InfoWindow?

Réponses:


120

Google a écrit un code pour vous aider. Voici quelques exemples: Exemple d'utilisation d'InfoBubble , de marqueurs stylisés et de fenêtre d'informations personnalisée (avec OverlayView).

Le code dans les liens ci-dessus emprunte des itinéraires différents pour obtenir des résultats similaires. L'essentiel est qu'il n'est pas facile de styliser InfoWindows directement, et il peut être plus facile d'utiliser la classe InfoBubble supplémentaire au lieu d'InfoWindow, ou de remplacer GOverlay. Une autre option serait de modifier les éléments de l'InfoWindow en utilisant javascript (ou jQuery), comme suggéré plus tard par ATOzTOA.

Le plus simple de ces exemples est probablement l'utilisation d'InfoBubble au lieu d'InfoWindow. InfoBubble est disponible en important ce fichier (que vous devez héberger vous-même):http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobubble/src/infobubble.js

Page de projet Github d'InfoBubble .

InfoBubble est très stylable, par rapport à InfoWindow:

 infoBubble = new InfoBubble({
      map: map,
      content: '<div class="mylabel">The label</div>',
      position: new google.maps.LatLng(-32.0, 149.0),
      shadowStyle: 1,
      padding: 0,
      backgroundColor: 'rgb(57,57,57)',
      borderRadius: 5,
      arrowSize: 10,
      borderWidth: 1,
      borderColor: '#2c2c2c',
      disableAutoPan: true,
      hideCloseButton: true,
      arrowPosition: 30,
      backgroundClassName: 'transparent',
      arrowStyle: 2
});

infoBubble.open();

Vous pouvez également l'appeler avec une carte et un marqueur donnés pour l'ouvrir:

infoBubble.open(map, marker);

Comme autre exemple, l'exemple de fenêtre d'information personnalisée étend la classe GOverlay de l'API Google Maps et l'utilise comme base pour créer une fenêtre d'informations plus flexible. Il crée d'abord la classe:

/* An InfoBox is like an info window, but it displays
 * under the marker, opens quicker, and has flexible styling.
 * @param {GLatLng} latlng Point to place bar at
 * @param {Map} map The map on which to display this InfoBox.
 * @param {Object} opts Passes configuration options - content,
 *   offsetVertical, offsetHorizontal, className, height, width
 */
function InfoBox(opts) {
  google.maps.OverlayView.call(this);
  this.latlng_ = opts.latlng;
  this.map_ = opts.map;
  this.offsetVertical_ = -195;
  this.offsetHorizontal_ = 0;
  this.height_ = 165;
  this.width_ = 266;

  var me = this;
  this.boundsChangedListener_ =
    google.maps.event.addListener(this.map_, "bounds_changed", function() {
      return me.panMap.apply(me);
    });

  // Once the properties of this OverlayView are initialized, set its map so
  // that we can display it.  This will trigger calls to panes_changed and
  // draw.
  this.setMap(this.map_);
}

après quoi il procède au remplacement de GOverlay:

InfoBox.prototype = new google.maps.OverlayView();

Vous devez alors remplacer les méthodes dont vous avez besoin: createElement, draw, removeet panMap. Cela devient plutôt compliqué, mais en théorie, vous dessinez vous-même un div sur la carte maintenant, au lieu d'utiliser une fenêtre d'informations normale.


@ShyamK Voici une question liée au style des fenêtres d'informations KML , qui pourrait vous aider. Je pense que la plupart des exemples de ma réponse ne sont peut-être pas applicables à KML (je ne suis pas sûr), mais peuvent facilement être ajustés pour fonctionner dans ce cas également.
Herman Schaaf

11
Il convient de noter que l'un de vos liens ici sont des exemples de l'objet InfoBox (un autre type de fenêtre d'informations) et non de l'objet InfoWindow (la fenêtre d'informations google d'origine). Il est bon de savoir si vous faites une recherche sur Google et si vous ne savez pas pourquoi vous pouvez trouver une nouvelle InfoBox () et une nouvelle InfoWindow (). InfoBox est le plus récent et il est plus facile de personnaliser IMO et il y a beaucoup plus que vous pouvez personnaliser. Un autre exemple de cela peut également être vu dans cette réponse SO
Don Vaughn

1
Oh, non, le dernier non plus: c'est aussi à propos d'InfoBox.
matteo

Bien, c'est ce que je cherchais, btw comment puis-je ajouter un bouton de fermeture?
Yusuf1494

36

Vous pouvez modifier toute l'InfoWindow en utilisant jquery seul ...

var popup = new google.maps.InfoWindow({
    content:'<p id="hook">Hello World!</p>'
});

Ici, l'élément <p> agira comme un crochet dans la véritable InfoWindow. Une fois que le domready se déclenche, l'élément deviendra actif et accessible en utilisant javascript / jquery, comme $('#hook').parent().parent().parent().parent().

Le code ci-dessous définit simplement une bordure de 2 pixels autour de l'InfoWindow.

google.maps.event.addListener(popup, 'domready', function() {
    var l = $('#hook').parent().parent().parent().siblings();
    for (var i = 0; i < l.length; i++) {
        if($(l[i]).css('z-index') == 'auto') {
            $(l[i]).css('border-radius', '16px 16px 16px 16px');
            $(l[i]).css('border', '2px solid red');
        }
    }
});

Vous pouvez faire quelque chose comme définir une nouvelle classe CSS ou simplement ajouter un nouvel élément.

Jouez avec les éléments pour obtenir ce dont vous avez besoin ...


4
Cela fonctionne pour moi (avec un parent en moins), et fonctionne avec les navigateurs acorss (opera, ff, ie, safari, chrome), mais ne fonctionne pas sous IE9.
johntrepreneur

Des accessoires pour inclure du code supplémentaire que je cherchais à utiliser. Merci
MetalPhoenix

J'obtiens «le popup n'est pas défini» lorsque je l'inclus dans le document (prêt), dans la fenêtre (chargement) ou si je le colle directement dans la console une fois la page chargée. Est-ce que je manque un fichier js externe ou quelque chose?
user1380540

Ce n'est pas une bonne idée car les logiques de rendu de Google map ne sont pas perpétuelles. Utilisez plutôt des fenêtres
contextuelles

5
google.maps.event.addListener(infowindow, 'domready', function() {

    // Reference to the DIV that wraps the bottom of infowindow
    var iwOuter = $('.gm-style-iw');

    /* Since this div is in a position prior to .gm-div style-iw.
     * We use jQuery and create a iwBackground variable,
     * and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
    */
    var iwBackground = iwOuter.prev();

    // Removes background shadow DIV
    iwBackground.children(':nth-child(2)').css({'display' : 'none'});

    // Removes white background DIV
    iwBackground.children(':nth-child(4)').css({'display' : 'none'});

    // Moves the infowindow 115px to the right.
    iwOuter.parent().parent().css({left: '115px'});

    // Moves the shadow of the arrow 76px to the left margin.
    iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 76px !important;'});

    // Moves the arrow 76px to the left margin.
    iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});

    // Changes the desired tail shadow color.
    iwBackground.children(':nth-child(3)').find('div').children().css({'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px', 'z-index' : '1'});

    // Reference to the div that groups the close button elements.
    var iwCloseBtn = iwOuter.next();

    // Apply the desired effect to the close button
    iwCloseBtn.css({opacity: '1', right: '38px', top: '3px', border: '7px solid #48b5e9', 'border-radius': '13px', 'box-shadow': '0 0 5px #3990B9'});

    // If the content of infowindow not exceed the set maximum height, then the gradient is removed.
    if($('.iw-content').height() < 140){
      $('.iw-bottom-gradient').css({display: 'none'});
    }

    // The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
    iwCloseBtn.mouseout(function(){
      $(this).css({opacity: '1'});
    });
  });

// CSS mis dans la feuille de style

.gm-style-iw {
  background-color: rgb(237, 28, 36);
    border: 1px solid rgba(72, 181, 233, 0.6);
    border-radius: 10px;
    box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
    color: rgb(255, 255, 255) !important;
    font-family: gothambook;
    text-align: center;
    top: 15px !important;
    width: 150px !important;
}

ce code a un problème avec la queue dans Chrome. Vous devez cliquer 2x pour que la queue affiche la bonne position
cpcdev


3

J'ai utilisé le code suivant pour appliquer du CSS externe:

boxText = document.createElement("html");
boxText.innerHTML = "<head><link rel='stylesheet' href='style.css'/></head><body>[some html]<body>";

infowindow.setContent(boxText);
infowindow.open(map, marker);

1
J'ai pu cibler directement le css en utilisant .gm-style> div> div: nth-child (3)> div: nth-child (4)> div> div> div: nth-child (2) {
Charlie- Greenman

1

Utilisez le plug- in InfoBox de la bibliothèque de l'utilitaire Google Maps. Cela facilite grandement le style / la gestion des fenêtres contextuelles de la carte.

Notez que vous devrez vous assurer qu'il se charge après l'API google maps:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=initMap" async defer></script>
<script src="/js/infobox_packed.js" async defer></script>

1

J'ai conçu une infowindow google map avec une image et du contenu comme ci-dessous.

entrez la description de l'image ici

map_script (juste pour la référence html infowindow)

for (i = 0; i < locations.length; i++) { 
    var latlng = new google.maps.LatLng(locations[i][1], locations[i][2]);
    marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: "<?php echo plugins_url( 'assets/img/map-pin.png', ELEMENTOR_ES__FILE__ ); ?>"
    });

    var property_img = locations[i][6],
    title = locations[i][0],
    price = locations[i][3],
    bedrooms = locations[i][4],
    type = locations[i][5],
    listed_on = locations[i][7],
    prop_url = locations[i][8];

    content = "<div class='map_info_wrapper'><a href="+prop_url+"><div class='img_wrapper'><img src="+property_img+"></div>"+
    "<div class='property_content_wrap'>"+
    "<div class='property_title'>"+
    "<span>"+title+"</span>"+
    "</div>"+

    "<div class='property_price'>"+
    "<span>"+price+"</span>"+
    "</div>"+

    "<div class='property_bed_type'>"+
    "<span>"+bedrooms+"</span>"+
    "<ul><li>"+type+"</li></ul>"+
    "</div>"+

    "<div class='property_listed_date'>"+
    "<span>Listed on "+listed_on+"</span>"+
    "</div>"+
    "</div></a></div>";

    google.maps.event.addListener(marker, 'click', (function(marker, content, i) {
        return function() {
            infowindow.setContent(content);
            infowindow.open(map, marker);
        }
    })(marker, content, i));
}

La chose la plus importante est CSS

 #propertymap .gm-style-iw{
    box-shadow:none;
    color:#515151;
    font-family: "Georgia", "Open Sans", Sans-serif;
    text-align: center;
    width: 100% !important;
    border-radius: 0;
    left: 0 !important;
    top: 20px !important;
}

 #propertymap .gm-style > div > div > div > div > div > div > div {
    background: none!important;
}

.gm-style > div > div > div > div > div > div > div:nth-child(2) {
     box-shadow: none!important;
}
 #propertymap .gm-style-iw > div > div{
    background: #FFF!important;
}

 #propertymap .gm-style-iw a{
    text-decoration: none;
}

 #propertymap .gm-style-iw > div{
    width: 245px !important
}

 #propertymap .gm-style-iw .img_wrapper {
    height: 150px;  
    overflow: hidden;
    width: 100%;
    text-align: center;
    margin: 0px auto;
}

 #propertymap .gm-style-iw .img_wrapper > img {
    width: 100%;
    height:auto;
}

 #propertymap .gm-style-iw .property_content_wrap {
    padding: 0px 20px;
}

 #propertymap .gm-style-iw .property_title{
    min-height: auto;
}

1
Merci! CSS ne fonctionnait pas mais cela se faisait facilement en utilisant des outils de développement et en passant directement à la classe, pas besoin de la chose de style .gm.
user2060451

-1

Vous pouvez également utiliser une classe css.

$('#hook').parent().parent().parent().siblings().addClass("class_name");

Bonne journée!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.