So I have this location that I have images for. I have about 15 images and I want there to only be 4 images on the infoWindow for the location and then you can click on the images and it will initialize a pop-up gallery slider. It currently does nothing when the image is clicked. I have 2 other locations that are going to have very similar set ups.
var locations = [ ['<div class="header">Lower</div><img id="myImg" src="1.png" alt="Snow" style="width:100%;max-width:300px"><div id="myModal" class="modal"><span class="close">×</span><img class="modal-content" id="img01"><div id="caption"></div>', 37.77, -122.43, 4], ]; function initMap() { var map= new google.maps.Map( document.getElementById('map'), { zoom: 14, center: { lat:37.78, lng:-122.44 } }); var infowindow = new google.maps.InfoWindow(); var marker, i; var markers = new Array(); for (i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map, }); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infowindow.setContent(locations[i][0], locations[i][6]); infowindow.open(map, marker); }; })(marker, i)); markers.push(marker); } // Get the modal var modal = document.getElementById("myModal"); // Get the image and insert it inside the modal - use its "alt" text as a caption var img = document.getElementById("myImg"); var modalImg = document.getElementById("img01"); var captionText = document.getElementById("caption"); img.onclick = function(){ modal.style.display = "block"; modalImg.src = this.src; captionText.innerHTML = this.alt; } // Get the <span> element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on <span> (x), close the modal span.onclick = function() { modal.style.display = "none"; } }
Here is the HTML document to go with it
<html> <head> <title>Vigor Locations</title> <meta name="viewport" content="initial-scale=1.0"> <meta charset="utf-8"> <style> html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; } #content { text-align: center; display: block; position: absolute; bottom: -8px; left: -20px; background-color: white; z-index: 10001; } .header { padding-right:2vw; font-weight: 600; font-size:26px; padding-bottom:15px; font-family:"IMB Plex Sans", sans-serif; } #myImg { border-radius: 5px; cursor: pointer; transition: 0.3s; } #myImg:hover {opacity: 0.7;} /* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ padding-top: 100px; /* Location of the box */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.9); /* Black w/ opacity */ } /* Modal Content (Image) */ .modal-content { margin: auto; display: block; width: 80%; max-width: 700px; } /* Caption of Modal Image (Image Text) - Same Width as the Image */ #caption { margin: auto; display: block; width: 80%; max-width: 700px; text-align: center; color: #ccc; padding: 10px 0; height: 150px; } /* Add Animation - Zoom in the Modal */ .modal-content, #caption { animation-name: zoom; animation-duration: 0.6s; } @keyframes zoom { from {transform:scale(0)} to {transform:scale(1)} } /* The Close Button */ .close { position: absolute; top: 15px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; transition: 0.3s; } .close:hover, .close:focus { color: #bbb; text-decoration: none; cursor: pointer; } /* 100% Image Width on Smaller Screens */ @media only screen and (max-width: 700px){ .modal-content { width: 100%; } } </style> </head> <body> <div id="map"></div> <!-- <script> </script> --> <script type="text/javascript" src="map_custom_2.js"></script> <!-- NOTE TO SELF: REVOKE API KEY AFTER ASSIGNMENT --> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBQfkiMFrFWpGHmP7YMFtlfQM6YEDqslNU&callback=initMap" async defer></script> </body> </html>
What am I doing wrong? I have read something about EventPropogation but I don’t know what that means and I don’t know how to disable it.
I have tried to make the onclick for the image a google event listener and that broke the whole map and made it a blank page.
Goal: Have an infowindow with clickable images in columns that when clicked open a popup with a gallery slider.
Current problem: On image click, nothing happens.
Advertisement
Answer
It looks like your issue is the HTML elements in the InfoWindow are not available in the DOM until after the InfoWindow is open. Your code is trying to access them before they exist in the DOM, which causes a javascript error: TypeError: Cannot set property 'onclick' of null
Related questions:
- Callback method for opening Google Maps InfoWindow
- Adding event listener to infowindow Google Maps v3
- How to detect button click in googlemaps infowindow
So add the code that needs to access the elements in the InfoWindow in an event listener for the domready
event on the InfoWindow:
google.maps.event.addListener(infowindow, 'domready', function() { // Get the modal var modal = document.getElementById("myModal"); // Get the image and insert it inside the modal - use its "alt" text as a caption var img = document.getElementById("myImg"); var modalImg = document.getElementById("img01"); var captionText = document.getElementById("caption"); img.onclick = function() { modal.style.display = "block"; modalImg.src = this.src; captionText.innerHTML = this.alt; } // Get the <span> element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on <span> (x), close the modal span.onclick = function() { modal.style.display = "none"; } })
code snippet:
var locations = [ ['<div class="header">Lower</div><img id="myImg" src="https://www.geocodezip.net/images/snow.png" alt="Snow" style="width:100%;max-width:300px"><div id="myModal" class="modal"><span class="close">×</span><img class="modal-content" id="img01"><div id="caption"></div>', 37.77, -122.43, 4], ]; function initMap() { var map = new google.maps.Map( document.getElementById('map'), { zoom: 14, center: { lat: 37.78, lng: -122.44 } }); var infowindow = new google.maps.InfoWindow(); var marker, i; var markers = new Array(); for (i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map, }); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infowindow.setContent(locations[i][0], locations[i][6]); google.maps.event.addListener(infowindow, 'domready', function() { // Get the modal var modal = document.getElementById("myModal"); // Get the image and insert it inside the modal - use its "alt" text as a caption var img = document.getElementById("myImg"); var modalImg = document.getElementById("img01"); var captionText = document.getElementById("caption"); img.onclick = function() { modal.style.display = "block"; modalImg.src = this.src; captionText.innerHTML = this.alt; } // Get the <span> element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on <span> (x), close the modal span.onclick = function() { modal.style.display = "none"; } }) infowindow.open(map, marker); }; })(marker, i)); markers.push(marker); } }
html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; } #content { text-align: center; display: block; position: absolute; bottom: -8px; left: -20px; background-color: white; z-index: 10001; } .gm-style .gm-style-iw-c { padding-top: 1vw !important; padding-left: 1vw !important; padding-right: 1vw !important; padding-bottom: 0.5vw !important; border-color: white; border-radius: 0px !important; } .gm-ui-hover-effect { width: 60px !important; height: 30px !important; } .gm-ui-hover-effect img { padding-top: 0.5vw; width: 30px !important; height: 30px !important; } #bodyContent img { text-align: center; } #bodyContent p { text-align: left; } .header { padding-right: 2vw; font-weight: 600; font-size: 26px; padding-bottom: 15px; font-family: "IMB Plex Sans", sans-serif; } #address { font-size: 16px; line-height: 5px; font-family: "IMB Plex Sans", sans-serif; } #address-2 { font-size: 16px; line-height: 5px; font-family: "IMB Plex Sans", sans-serif; padding-bottom: 29px; } #hours { font-size: 12px; line-height: 20px; font-family: "IMB Plex Sans", sans-serif; } .row { display: flex; padding: 0 0px; } /* Create four equal columns that sits next to each other */ .column { flex: 25%; max-width: 25%; padding-top: 36px; padding-bottom: 0px; padding-left: 0px; padding-right: 18px; } .column img { margin-top: 8px; vertical-align: middle; height: 85px; } #myImg { border-radius: 5px; cursor: pointer; transition: 0.3s; } #myImg:hover { opacity: 0.7; } /* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ padding-top: 100px; /* Location of the box */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0, 0, 0); /* Fallback color */ background-color: rgba(0, 0, 0, 0.9); /* Black w/ opacity */ } /* Modal Content (Image) */ .modal-content { margin: auto; display: block; width: 80%; max-width: 700px; } /* Caption of Modal Image (Image Text) - Same Width as the Image */ #caption { margin: auto; display: block; width: 80%; max-width: 700px; text-align: center; color: #ccc; padding: 10px 0; height: 150px; } /* Add Animation - Zoom in the Modal */ .modal-content, #caption { animation-name: zoom; animation-duration: 0.6s; } @keyframes zoom { from { transform: scale(0) } to { transform: scale(1) } } /* The Close Button */ .close { position: absolute; top: 15px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; transition: 0.3s; } .close:hover, .close:focus { color: #bbb; text-decoration: none; cursor: pointer; } /* 100% Image Width on Smaller Screens */ @media only screen and (max-width: 700px) { .modal-content { width: 100%; } }
<!DOCTYPE html> <html> <head> <title>Vigor Locations</title> <meta name="viewport" content="initial-scale=1.0"> <meta charset="utf-8"> </head> <body> <div id="map"></div> <!-- <script> </script> --> <script type="text/javascript" src="map_custom_2.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBQfkiMFrFWpGHmP7YMFtlfQM6YEDqslNU&callback=initMap" async defer></script> </body> </html>