Is there a way of preventing a Google Maps (JS, v3) map being displayed from the get-go? I'm doing some pre-processing and would like to show my 'Loading' spinner until everything is good to go (more eloquently put, hide the map -- e.g. the container div – until all pre-processing is complete – at which point, show the map).
Hooking up the map's idle event doesn't help that much, since the map is already displayed when this event hits.
I know that the container div gets inline-styled by GMaps after loading, my first idea was to clear out the style attribute (whilst listening to the idle event), but it would be interesting to see if there is a way of creating the map and not displaying it until all pre-processing is done.
Maybe by using an argument to the new google.maps.Map constructor, or a MapOption ?
Any thoughts on this?
Thank you in advance!
Also remember to call:
google.maps.event.trigger(map, 'resize');
if you have changed the size of the <div>. A display:none <div> has no size.
Or you could just hide it like with css visablility or css opacity.
$("#GoogleMap").css({ opacity: 0, zoom: 0 });
initialize();
google.maps.event.addListener(map,"idle", function(){
$('#Loader').hide();
$("#GoogleMap").css({ opacity: 1, zoom: 1 });
});
This works for me. I'm using the JQuery library.
$(document).ready(function(){
$('#Checkbox').click(function(){
$('#googleMapDiv').toggle();
initialize(); // initialize the map
});
});
another way to show the hidden map when map is first time rendering the <div> is to set style: visibility.
When firstly hidden, use visibility = hidden; to show use visibility = visible
the reason is: visibility:hidden means that the contents of the element will be invisible, but the element stays in its original position and size.
this works fine for me, I use jquery tabs
setTimeout(function() {
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(default_lat, default_lng));
map.setZoom(default_map_zoom);
}, 2000);
om this link https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448
This will work
google.maps.event.addListener(map, "idle", function ()
{
google.maps.event.trigger(map, 'resize');
});
better way:
gmap.redraw = function() {
gmOnLoad = true;
if(gmOnLoad) {
google.maps.event.trigger(gmap, "resize");
gmap.setCenter(gmlatlng);
gmOnLoad = false;
}
}
and in show click event:
$("#goo").click(function() {
if ($("#map_canvas").css("display") == "none") {
$("#YMapsID").toggle();
$("#map_canvas").toggle();
if (gmap != undefined) {
gmap.redraw();
}
}
});
depending on what you are doing another posibility could be to have multiple bools you set to true when each process is done.
For example:
if you have a geocode service running which you want to wait for, you could have a var called
GeoState
and in the result part of the geocoder set GeoState to true,
then have a timed function check if all the services have returned true, when they have, make the map visible.
Related
Basically I'd like to be able to add a standalone button to trigger the Google Map I've embedded onto my site to enter fullscreen mode. I haven't had any luck locating an answer as of yet, so any help would be greatly appreciated.
Currently the only way to enter fullscreen mode is by clicking the fullscreen button inside the map (at the top right). I imagine I just need to assign the same command that this button has, although I'm not sure if that would work on an element outside of the map.
Thanks in advance!
I don't know if you solved this, but i've recently faced same problem and I want to share the way I did it.
Basically what I've done is show the default fullscreen control then find it in the dom using its title, then I manually fired click event.
When I verified that worked, I written a css to hide the button.
This is a little bit hacky but it works!
function initMap() {
var container = $('#container').get(0);
var map = new google.maps.Map(container, {
center: {lat: -39.000, lng: -60.000},
zoom: 3,
fullscreenControl: true
});
$('#fullscreen').click(function() {
$('#container div.gm-style button[title="Toggle fullscreen view"]').trigger('click');
});
}
#container div.gm-style > button[title="Toggle fullscreen view"] {
display: none;
}
See this fiddle
Hope this help.
You could simply call requestFullscreen method from the map's container. Like this:
$('[data-id="map_go_fullscreen"]').click(function(e){
var map = document.querySelector(".gm-style");
map.requestFullscreen();
});
Docs: https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen
map = new google.maps.Map(document.getElementById('map') , {
zoom: 6,
center: latLng,
gestureHandling: 'none'
});
initFullscreenControl(map);
function initFullscreenControl (map) {
var elementToSendFullscreen =
map.getDiv().firstChild;
var fullScreenControl =
document.querySelector('.fullscreen-control');
fullScreenControl.onclick = function() {
elementToSendFullscreen.requestFullscreen();
};
};
<div class="controls fullscreen-control">
<button title="Toggle Fullscreen"> Show full screen </button>
</div>
<div id = "map"></div>
I know how to display an infoWindow, but I have a problem capturing the event from a button displayed there.
var view = Marionette.LayoutView.extend({
...
methodA: function(){
me.showMapInfoWindow(marker, "Test popup<button onclick='methodB()'>Click me</button>")
me.infoWindow.open(me.map, marker);
},
methodB: function(){
console.log("test");
}
}
When I click the button, I get an error when calling methodB saying it's not defined. I've tried with me.methodB, etc...but no luck there. How can I fix this?
Here is a JSFiddle showing an InfoWindow populated with a DOM node, rather than a HTML string. This way, we can use jQuery to add a programmatic event to the DOM, which can access the current scope, as shown.
var $infoWindow = $('<div>Test popup<button>Click me</button></div>');
$infoWindow.find('button').click(_.bind(this.methodB, this));
me.showMapInfoWindow(marker, $infoWindow.get(0));
me.infoWindow.open(me.map, marker);
Answer to First Question
Here is a JSFiddle showing an InfoWindow firing a global function. In this case I had to set the function to Window scope, though I believe this is due to the JSFiddle environment.
window.myFunction = function() {
window.alert("function fired!");
}
...
var html = '<button onclick=\'myFunction()\'>Click me</button>';
if you want to debug the scope, I'd suggest using the debugger statement:
var html = '<button onclick=\'debugger;\'>Click me</button>';
My Google map is not working
I used this tab view
http://www.petelove.com/responsiveTabs/
My google map init() is:
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: <?php echo $lat; ?>, lng: <?php echo $long; ?>},
zoom: 3
});
When i run my google map in first tab it's working fine.
But when i load in second tab. I just get view only. NO MAP DISPLAYING.....
This question has been asked about a thousand times on this website. You should first search before asking again.
The key is that your map is hidden when initialized and therefore, you need to trigger a resize event once the tab has been shown.
google.maps.event.trigger(map, "resize");
Regarding the "tabs" library: choose a library that exposes events. This doesn't seem to be the case (or it is not documented) with the library you choose.
A quick example: Bootstrap tabs
This library exposes events:
Events
When showing a new tab, the events fire in the following order:
hide.bs.tab (on the current active tab)
show.bs.tab (on the to-be-shown tab)
hidden.bs.tab (on the previous active tab, the same one as for the hide.bs.tab event)
shown.bs.tab (on the newly-active just-shown tab, the same one as for the show.bs.tab event)
This way, you have full control over what happens with your tabs. You know when it's shown, hidden, etc.
So you could use something like:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// Trigger map resize when tab is shown
google.maps.event.trigger(map, "resize");
});
Edit:
If you need to reset the center, do it here:
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// Trigger map resize when tab is shown
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(<?php echo $lat; ?>, <?php echo $long; ?>));
});
I got this working with just CSS no JS needed:
.tab-content > .tab-pane {
display: block;
height:0;
overflow:hidden;
}
.tab-content > .active {
display: block;
height:auto;
}
Keval, you need to trigger a resize when you display the map.
According to the documentation, you need to trigger a resize event like by
google.maps.event.trigger(map, "resize");
I created a fiddle by adding a tab to the demo page. I used the attrchange jquery plugin to listen to all the changes made to the mapTab, the tab that contains the Google Maps, just to make things simple.
Look at this demo on jsfiddle.
if you take out the listener, the maps would not show unless you click the Resize Map button. Hope this make things clear.
I'm using google map fitBounds, then I use map.setZoom to zoom-in one level (after google finds the best zoom level to fit my markers), then I want to check weather my markers are visible in viewport or not, how can I do so? it seems that map.getBounds().contains doesn't work, please take a look at this fiddle: fiddle
I want to check my marker is visible or not:
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains("35.700592","51.394773"))
alert('ok');
but there seems to be an error
//alert("the zoom level is now "+map.getZoom());
});
Why do you think "35.700592","51.394773" is a google.maps.LatLng? It is two strings separated by a comma.
This won't work:
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains("35.700592","51.394773"))
alert('ok');
});
This is the correct way to use "contains" (with a LatLng object):
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains(new google.maps.LatLng(35.700592,51.394773)))
alert('ok');
});
And you probably want to make an array containing your markers and use .getPosition() on the markers
http://jsfiddle.net/Npu36/10/embedded/result/
I made this fiddle
http://jsfiddle.net/nAb6N/10/
As you can see I have 2 animators , a element and body class,
I am adding class to body after the first click on a element but once I click on body is not closing it. If I define animators as
var animators = $$('#opendiv,body');
it works ok except that I do not want the div to open on body click. I need it to close on body click.
Any help is appreciated.
Thank you!
Right. Seems as if you really require an outerClick pattern to close. Here's the one that is most notably used within mootools devs, allowing you to create a custom event, based on click:
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
The way it works is: it is based on a normal click. upon adding, it adds the callback as a click event on the document. when a click happens within the element itself,it stops bubbling via event.stopPropagation();, else, it will bubble and the callback will run.
here's how it ties together after the above:
http://jsfiddle.net/dimitar/nAb6N/13/
(function() {
var opener = $('opendiv');
var boxtoopen = $('box');
boxtoopen.set('morph', {
duration: 700,
transition: 'bounce:out'
});
boxtoopen.addEvent('outerClick', function(event) {
boxtoopen.morph(".openOff");
opener.removeClass("hide");
});
opener.addEvent('click', function(e) {
e.stop();
boxtoopen.morph(".openOn");
this.addClass("hide");
});
})();
I have also 'outsourced' the morph properties to the CSS as it makes more sense, semantically.
P.S. note that you need mootools 1.4.3 or 1.4.5, but not 1.4.4 as there's a morph bug to do with units in that release. the jsfiddle above uses 1.4.6 (mootools edge).