Instructions for creating a Google Maps overlay that hovers above the zoom bar

Let me share my workaround for creating an overlay and dealing with z-index issues when using Google Maps API. The problem arises when dragging the map and the overlay ends up behind control elements like the zoom bar. No matter how much I adjust the z-index, it doesn't work as expected due to the structure of the parent elements having lower z-index values. If I increase the z-index of the parents, the controls end up hidden under the map itself. This is because the overlay and controls are in separate divs each with their own z-index.

<html>
<head>
    <style type="text/css">
        #map {
            width: 600px;
            height: 500px;
        }
    </style>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript">
        var map;
        TestOverlay.prototype = new google.maps.OverlayView();
        /** @constructor */
        function TestOverlay(map) {
            this.setMap(map);
        }

        /**
         * onAdd is called when the map's panes are ready and the overlay has been
         * added to the map.
         */
        TestOverlay.prototype.onAdd = function() {
            var div = document.createElement('div');
            div.innerHTML = "I want the zoombar to go behind me.";
            div.style.backgroundColor = "white";
            div.style.position = "relative";
            div.style.fontSize = "20px";
            // Add the element to the "overlayLayer" pane.
            var panes = this.getPanes();
            panes.overlayLayer.appendChild(div);
        };

        TestOverlay.prototype.draw = function() {
        };

        // The onRemove() method will be called automatically from the API if
        // we ever set the overlay's map property to 'null'.
        TestOverlay.prototype.onRemove = function() {
        };
        function init() {
            var mapCenter = new google.maps.LatLng(-35.397, 150.644);
            map = new google.maps.Map(document.getElementById('map'), {
                zoom: 8,
                center: mapCenter
            });
            new TestOverlay(map);
        }
        google.maps.event.addDomListener(window, 'load', init);
    </script>
</head>
<body>
    <div id="map"></div>
</body>

I've come up with a somewhat hacky solution to handle the overlay issue with the controls while using the Google Maps API. Here's how I managed to make it work:

<html>
    <head>
        <style type="text/css">
            #map {
                width: 600px;
                height: 500px;
            }
        </style>
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript">
            var map;
            var ol;
            TestOverlay.prototype = new google.maps.OverlayView();
            /** @constructor */
            function TestOverlay(map) {
                this.setMap(map);
            }

            /**
             * onAdd is called when the map's panes are ready and the overlay has been
             * added to the map.
             */
            TestOverlay.prototype.onAdd = function() {
                var div = document.createElement('div');
                div.id = "dummy";
                // Add the element to the "overlayLayer" pane.
                var panes = this.getPanes();
                panes.overlayMouseTarget.appendChild(div);
            };

            TestOverlay.prototype.draw = function() {
            };

            // The onRemove() method will be called automatically from the API if
            // we ever set the overlay's map property to 'null'.
            TestOverlay.prototype.onRemove = function() {
            };
            function init() {
                var mapCenter = new google.maps.LatLng(-35.397, 150.644);
                map = new google.maps.Map(document.getElementById('map'), {
                    zoom: 8,
                    center: mapCenter
                });
                google.maps.event.addListenerOnce(map, 'idle', function() {
                    var div = document.createElement('div');
                    div.id = "overlay";
                    div.className = "gmnoprint";
                    div.innerHTML = "Yes, the controls go behind me ;)";
                    div.style = "background-color:white;z-index:100000000000;position:absolute";
                    $(".gm-style").append(div);
                });
                google.maps.event.addListener(map, 'drag', function() {

                    $("#overlay").css("left", $("#dummy").parent().parent().parent().css("left"))
                    $("#overlay").css("top", $("#dummy").parent().parent().parent().css("top"))
                });
                ol = new TestOverlay(map);
            }
            google.maps.event.addDomListener(window, 'load', init);
        </script>
    </head>
    <body>
        <div id="map"></div>
    </body>
</html>

To overcome the z-index issue, I created a dummy overlay placed at the same level as the controls, and used the jQuery library to dynamically position my overlay div based on the dummy div during the drag event. It may not be the most elegant solution but it gets the job done!

Answer №1

It has come to my understanding that custom overlays consist of 6 layers:

  1. mapPane
  2. overlayLayer
  3. overlayShadow
  4. overlayImage
  5. floatShadow
  6. overlayMouseTarget
  7. floatPane

Regrettably, the design does not allow for overlays to be placed on top of controls, as it could potentially render the map ineffective.

If you haven't done so already, I recommend checking out the developers' website for information on custom overlays. There might be a solution available that hasn't been discovered yet.

https://developers.google.com/maps/documentation/javascript/customoverlays#hide_show

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Web server experiencing issues with loading scripts and CSS files

After successfully building my project using CodeIgniter on localhost, I encountered an issue when trying to run it on a webhost. The site was functional but the design elements such as scripts and stylesheets were not loading properly. Before uploading t ...

jQuery Animation Issue: SlideDown Effect Not Working as Expected

I'm feeling quite confused about this situation. I've been attempting to utilize the slideDown function in jQuery, but when I click on the 'information' div, it just jumps instead of animating smoothly. I suspect that one of the cause ...

Is there a way to incorporate an 'ended' feature into the .animate() function?

I'm currently working on a jQuery statement where I want to activate pointer events once the button animation is finished. However, I'm unsure how to incorporate an ended or complete function. Any suggestions on how to approach this? $('#ce ...

Changing the order of element names depending on their location within the parent element using jQuery

<div class="content"> <div> <input type="text" name="newname[name]0"/> <div> <input type="text" name="newname[utility]0"/> <div> <textarea name="newname[text]0 ...

What methods can I use to identify my current page location and update it on my navigation bar accordingly?

My latest project involves a fixed sidebar navigation with 3 divs designed to resemble dots, each corresponding to a different section of my webpage. These sections are set to occupy the full height of the viewport. Now, I'm facing the challenge of de ...

Banner advertisement on a webpage

Currently, I am working on a website project for clients who are interested in having background ads displayed throughout the entire site. In terms of coding this feature with CSS, it is relatively straightforward: body { background-image: url('a ...

Internet Explorer (on mobile devices) does not display submenus when touched

Hello, I have a query about displaying a sublist on touch. I have created a sublist that is supposed to show up when you hover over it. You can view the demo here: @import url(//fonts.googleapis.com/css?family=Titillium+Web:400,200,300,600,700); body { ...

Adjusting the size of a React element containing an SVG (d3)

In my simple react app, I have the following component structure: <div id='app'> <Navbar /> <Graph /> <Footer /> </div> The Navbar has a fixed height of 80px. The Footer has a fixed height of 40px. The Graph i ...

How can you implement a transform transition toggle when a user clicks on an element

Check out this CodePen example for a cool overlay animation: https://codepen.io/pen/MoWLrZ Experience the unique animation of two overlays as you click for the first time. However, on the second click, watch as both overlays seamlessly return to their ori ...

The MVC 5 view is unable to display an HTML image when adding it within an appended div

Currently, I am working with ASP.net MVC5 at a novice level. I'm faced with the challenge of creating a div that displays an image using a JavaScript function. Here is the code snippet I have: function showLoadingImage() { $('#submit_Em ...

Mysterious additional spacing

I am facing an issue with aligning my div elements with a 20px margin. Despite setting the margin to 20px, I notice that there are additional 4 pixels rendered when I view it on the browser. Below is the code snippet: .block{ width:50px; height:50 ...

fluid columns gliding from side to side

I'm currently working with Bootstrap to design responsive columns. My goal is to have the next column of content slide in from either the left or right side when the user clicks on the respective arrow button. While I have found solutions for fixed w ...

How can I achieve a smooth opacity transition without using jQuery?

Although I understand that JQuery offers functions for this purpose, I am interested in finding a solution using only pure javascript. Is there a way to change the CSS opacity setting over time? Perhaps utilizing a unix time stamp with millisecond precisi ...

Django - issue with table display showing empty row due to query set

In my project, I have two models: one named Season and the other one named Game: # Season class Season(models.Model): teams = models.ManyToManyField('Team', related_name='season_teams', blank=True) current = models.BooleanF ...

The enchanting world of CSS background scrolling animations

I am currently developing a website where I have split the hero/header into two sections - one on the left with information and the other on the right with a graphic. I wanted to add a simple parallax effect to the image on the right side, so I used backgr ...

Having difficulty incorporating a video into the background

After searching online and attempting two different methods, I am still unable to achieve the desired result. I want a video to cover the entire background of my webpage. Here is what I have tried: CSS - video#bgvid { position: fixed; top: 50%; ...

Add a sublime project with a specific directory path

Currently, I am using Sublime Text 2 for a project that is structured as follows: public vendors a.css b.css myfile.less myfile.css (compiled) I am facing an issue where I need to exclude the css files from the main 'public' folder (specifi ...

Tips for adjusting font size automatically to fit within its parent container every time

On my blog, the post titles are displayed in a div with a video playing in the background. The length of the title varies, ranging from 2 words to over 20 words. When the title is too long, it may overflow from its parent container where the video is playi ...

prettyPhoto popup exceeds maximum width and height limitations

I am currently using the most up-to-date version from No Margin for Errors and I have set allow_resize to true. However, the size of the display is still too large. Is there a way to set a maximum width/height? I have already configured the viewport as fo ...

Display radio buttons depending on the selections made in the dropdown menu

I currently have a select box that displays another select box when the options change. Everything is working fine, but I would like to replace the second select box with radio buttons instead. Can anyone assist me with this? .sub{display:none;} <sc ...