Looking to disable the Google Map when browsed on a mobile device. Currently running CSS to hide the div if the browser window is 600px or below.
#media only screen and (max-width: 600px) {
.mapCanvas {
display: none;
}
}
How can you disable the JS from querying the Google Maps API if the browser is 600px or smaller?
So that it won't query the API server when the map isn't even displayed.
<div id="mapCanvas"></div>
<script>
function initMap() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap'
};
// Display a map on the web page
map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
map.setTilt(50);
// Multiple markers location, latitude, and longitude
var markers = [ <?php echo $js_markers; ?>
];
// Info window content
var infoWindowContent = [ <?php echo $js_content; ?>
];
// Add multiple markers to map
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Place each marker on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Add info window to marker
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Center the map to fit all markers on the screen
map.fitBounds(bounds);
}
// Set zoom level
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(7);
google.maps.event.removeListener(boundsListener);
});
}
// Load initialize function
google.maps.event.addDomListener(window, 'load', initMap);
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=???&callback=initMap"></script>
Don't include the google maps API JS file if its mobile
Something like
if (typeof window.orientation !== 'undefined') { ... }
Related
I'm trying to close a open google maps infowindow by clicking a marker again. Currently there are only questions about how to close all other infowindows when clicking the map or other markers.
How to close an open google maps infowindow by clicking the same marker again? Currently I can only close an infowindow by clicking the cross on the top right corner of the infowindow.
This is what I tried but it doesn't even open the infowindow:
EncoreMarker.addListener('click', function () {
if (EncoreInfoCard.open) {
EncoreInfoCard.close(map, EncoreMarker);
}
else {
EncoreInfoCard.open(map, EncoreMarker);
}
});
Your code won't work because open is a function that opens the InfoWindow, not a boolean that tells whether it is open or not.
This works for me:
EncoreMarker.addListener('click', function () {
// create a custom property of the InfoWindow, defaults to a value that evaluates as false
if (EncoreInfoCard.isOpen) {
EncoreInfoCard.close(map, EncoreMarker);
EncoreInfoCard.isOpen = false;
}
else {
EncoreInfoCard.open(map, EncoreMarker);
EncoreInfoCard.isOpen = true;
}
});
proof of concept fiddle
code snippet:
// This example displays a marker at the center of Australia.
// When the user clicks the marker, an info window opens.
// When the user clicks the makrer again, the info window closes.
function initMap() {
var uluru = {
lat: -25.363,
lng: 131.044
};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var EncoreInfoCard = new google.maps.InfoWindow({
content: "<b>This is a Test</b>"
});
google.maps.event.addListener(EncoreInfoCard, 'closeclick', function() {
EncoreInfoCard.isOpen = false;
});
var EncoreMarker = new google.maps.Marker({
position: uluru,
map: map,
title: 'Uluru (Ayers Rock)'
});
EncoreMarker.addListener('click', function() {
if (EncoreInfoCard.isOpen) {
EncoreInfoCard.close(map, EncoreMarker);
EncoreInfoCard.isOpen = false;
} else {
EncoreInfoCard.open(map, EncoreMarker);
EncoreInfoCard.isOpen = true;
}
});
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
For some reason, even though my Google map is showing, there are strange grey bands/lines running through the map (image link below).
Just for reference it uses the places API to search for locations.
Screenshot of the map issue
Anybody have any ideas why this might be? Here's the code for the map:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places"></script>
<script type="text/javascript">
function search_map_init() {
var args = {
disableDefaultUI : true,
center : new google.maps.LatLng(51.6948168, -0.6433884),
mapTypeId : google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
zoom : 12,
styles : [{"featureType":"water","elementType":"geometry","stylers":[{"color":"#e9e9e9"},{"lightness":17}]},{"featureType":"landscape","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry.fill","stylers":[{"color":"#ffffff"},{"lightness":17}]},{"featureType":"road.highway","elementType":"geometry.stroke","stylers":[{"color":"#ffffff"},{"lightness":29},{"weight":0.2}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":18}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"},{"lightness":16}]},{"featureType":"poi","elementType":"geometry","stylers":[{"color":"#f5f5f5"},{"lightness":21}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#dedede"},{"lightness":21}]},{"elementType":"labels.text.stroke","stylers":[{"visibility":"on"},{"color":"#ffffff"},{"lightness":16}]},{"elementType":"labels.text.fill","stylers":[{"saturation":36},{"color":"#333333"},{"lightness":40}]},{"elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"geometry","stylers":[{"color":"#f2f2f2"},{"lightness":19}]},{"featureType":"administrative","elementType":"geometry.fill","stylers":[{"color":"#fefefe"},{"lightness":20}]},{"featureType":"administrative","elementType":"geometry.stroke","stylers":[{"color":"#fefefe"},{"lightness":17},{"weight":1.2}]}]
};
var map = new google.maps.Map(document.getElementById('map-canvas'), args);
var marker_url = {
url : 'IMG_URL',
scaledSize : new google.maps.Size(48, 65)
};
var searchBox = new google.maps.places.SearchBox(document.getElementById('pac-input'));
map.controls[google.maps.ControlPosition.TOP_CENTER].push(document.getElementById('pac-input'));
google.maps.event.addListener(searchBox, 'places_changed', function() {
searchBox.set('map', null);
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
(function(place) {
var marker = new google.maps.Marker({
position: place.geometry.location,
icon : marker_url
});
marker.bindTo('map', searchBox, 'map');
google.maps.event.addListener(marker, 'map_changed', function() {
if (!this.getMap()) {
this.unbindAll();
}
});
bounds.extend(place.geometry.location);
}(place));
var new_address = $('#pac-input').val();
var new_lat = place.geometry.location.lat();
var new_lng = place.geometry.location.lng();
$('input[name="post[meta_input][map][address]"]').val(new_address);
$('input[name="post[meta_input][map][lat]"]').val(new_lat);
$('input[name="post[meta_input][map][lng]"]').val(new_lng);
}
map.fitBounds(bounds);
searchBox.set('map', map);
map.setZoom(Math.min(map.getZoom(),12));
});
return map;
}
google.maps.event.addDomListener(window, 'load', search_map_init);
</script>
Note: I've replaced the API key and image URL with API_KEY and IMG_URL in the code above.
I was setting min-width in the CSS for something else which was also effecting the map display. Problem solved!
How can you show data for individual markers?
I am able to show custom data when a mouseover occurs on a Google Maps API markerclusterer cluster but can't work out how to do the same for an individual marker (i.e. when you zoom in to a cluster until you see individual markers).
The code which shows data for the clusters is:
var markerClusterer = null;
var map = null;
var imageUrl = 'http://chart.apis.google.com/chart?cht=mm&chs=24x32&' +
'chco=FFFFFF,008CFF,000000&ext=.png';
google.maps.event.addDomListener(window, 'load', initialize);
function refreshMap() {
if (markerClusterer) {
markerClusterer.clearMarkers();
}
var markers = [];
var markerImage = new google.maps.MarkerImage(imageUrl,
new google.maps.Size(24, 32));
for (var i = 0; i < numItemsToShow; ++i) {
var latLng = new google.maps.LatLng(itemsToShow[i].lat, itemsToShow[i].long);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
var zoom = parseInt(document.getElementById('zoom').value, 10);
var size = parseInt(document.getElementById('size').value, 10);
var style = parseInt(document.getElementById('style').value, 10);
zoom = zoom == -1 ? null : zoom;
size = size == -1 ? null : size;
style = style == -1 ? null: style;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
// Respond to mouseover on marker cluster
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerClusterer, 'mouseover', function (cluster) {
// do something with this cluster ...
infoWindow.setContent("Mouseover<br>"+cluster.getCenter().toUrlValue());
infoWindow.setPosition(cluster.getCenter());
infoWindow.open(map);
});
// HOW TO RESPOND TO MOUSEOVER ON INDIVIDUAL MARKER?
}
Add a click listener to the google.maps.Marker objects:
var latLng = new google.maps.LatLng(itemsToShow[i].lat, itemsToShow[i].long);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
// slightly modified from Google Maps JS API v3 - Simple Multiple Marker Example
// http://stackoverflow.com/questions/3059044/google-maps-js-api-v3-simple-multiple-marker-example
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(ItemsToShow[i].lat+","+itemsToShow[i].long);
infowindow.open(map, marker);
}
})(marker, i));
I have a problem with the wrapper for the Google map. The class is set by document ready to display:none. If I click on the link the map must be set on show(). It works, but the map doesn't display right.
Here's a screenshot:
And here is my JSFiddle example.
Here my HTML code:
show map
<div class="advertise-mapper">
<div class="responsiveContaineradv">
<div id="map-canvas" class="map-adver"></div>
</div>
</div>
Here my JS Code:
jQuery(document).ready(function() {
jQuery(document).on("click", ".advertise-map", function(e) {
e.preventDefault();
jQuery('.advertise-mapper').show();
});
});
var map;
function initialize() {
var locations = [
['<h4>BMX Golden MILE 20 Fahrrad</h4>250.00 €<br>zur Kleinanzeige', 51.4627921, 6.9787572],
['<h4>Apple Macbook Air 13 A1466 Juni 2013</h4>800.00 €<br>zur Kleinanzeige', 51.665041, 7.631431],
['<h4>Apple iPod nano 16 GB Grün 6. Generation</h4>60.00 € VB<br>zur Kleinanzeige', 51.5096015, 7.377755],
];
var myLatlng = new google.maps.LatLng(51.513587, 7.465298);
var mapOptions = {
zoom: 11,
center: myLatlng
}
var infowindow = new google.maps.InfoWindow({
maxWidth: 360
});
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var markers = new Array();
for (var i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
animation: google.maps.Animation.DROP
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
function autoCenter() {
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].position);
}
// Fit these bounds to the map
map.fitBounds(bounds);
}
autoCenter();
}
google.maps.event.addDomListener(window, 'load', initialize);
How can I make the map display correctly when shown?
I would make a few small corrections, the most important of which goecodezip mentioned in the comments.
In your onclick of .advertise-map, add the map resize (important) and autoCenter (optional).
jQuery(document).on("click",".advertise-map",function(e){
e.preventDefault();
jQuery('.advertise-mapper').show();
google.maps.event.trigger(map, "resize");
autoCenter();
});
Next, I'd make 'markers' a global variable:
var map;
var markers = new Array();
Finally, I'd move the autoCenter() function out from the initialize function.
With all those changes, I believe this is what you're looking for: http://jsfiddle.net/2xn7wywo/22/
I am trying to get google maps to load, then zoom into my marker, but I have something wrong with my javascript, as the scope of the map is not visible, despite it being defined globally.
Any ideas what I am doing wrong ?
Many thanks
Mark
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script src="js/jquery-1.10.1.min.js"></script>
<link href="css/default.css" rel="stylesheet">
<!--
Include the maps javascript with sensor=true because this code is using a
sensor (a GPS locator) to determine the user's location.
See: https://developers.google.com/apis/maps/documentation/javascript/basics#SpecifyingSensor
-->
<script src="https://maps.googleapis.com/maps/api/js?v=3.12&sensor=true"></script>
<script>
//START Global Variables
var geocoder;
var map;
var marker;
var initialZoomLevel = 7;
var endZoomLevel = 16;
var zoomTimeInterval_ms = 1000;
var mapIcon = {
url: "images/im_here.png",
// This marker is 130 pixels wide by 120 pixels tall
size: new google.maps.Size(130,120),
//scale image so it works with retina displays
scaledSize: new google.maps.Size(65,60),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor point is be middle of the base
anchor: new google.maps.Point(32.5,60)
};
var mapIcon_shadow = {
url: "images/im_here_shadow.png",
// This shadow is 191 pixels wide by 120 pixels tall
size: new google.maps.Size(191,120),
//scale image so it works with retina displays
scaledSize: new google.maps.Size(95.5,60),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor point is be middle of the base
anchor: new google.maps.Point(32.5,60)
};
//Enable the visual refresh
google.maps.visualRefresh = true;
//END Global Variables
/** Initialise function to render the map */
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: initialZoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
streetViewControl: false,
zoomControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
// set home location
home = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
// the marker where you are
marker = new google.maps.Marker({
map: map,
position: pos,
icon: mapIcon,
shadow: mapIcon_shadow,
draggable: true
});
codeLatLng(pos);
map.panTo(pos);
google.maps.event.addListener(marker, 'dragend', function(a) {
//alert('LatLng is '+a.latLng.lat()+ " "+ a.latLng.lng());
codeLatLng(a.latLng);
});
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
// Create the DIV to hold the control and
// call the HomeControl() constructor passing
// in this DIV.
//var homeControlDiv = document.createElement('div');
//var homeControl = new HomeControl(homeControlDiv, map);
//homeControlDiv.index = 1;
//map.controls[google.maps.ControlPosition.TOP_CENTER].push(homeControlDiv);
smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
function codeLatLng(markerLatLang) {
//var latlng = new google.maps.LatLng(latLng.lat(), latLng.lng());
geocoder.geocode({'latLng': markerLatLang}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
name = results[0].formatted_address;
latlongStr = "LAT = ["+markerLatLang.lat()+"] LNG = ["+markerLatLang.lng()+"]";
//alert("name = "+name);
$('#address').html(name);
$('#latlong').html(latlongStr);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
}
/**
* The HomeControl adds a control to the map that simply
* returns the user to home. This constructor takes
* the control DIV as an argument.
* #constructor
*/
/** TODO need to rewite this as normal div, not on map **/
function HomeControl(controlDiv, map) {
// Set CSS styles for the DIV containing the control
// Setting padding to 5 px will offset the control
// from the edge of the map
controlDiv.style.padding = '5px';
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to set the map to Start Location';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Helvetica,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.style.zIndex = "100";
controlText.innerHTML = '<b>Reset Map</b>';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map back to home
google.maps.event.addDomListener(controlUI, 'click', function() {
marker.setPosition(home);
map.setCenter(home);
});
}
// the smooth zoom function
function smoothZoom (map, max, cnt) {
if (cnt >= max) {
return;
}
else {
z = google.maps.event.addListener(map, 'zoom_changed', function(event){
google.maps.event.removeListener(z);
self.smoothZoom(map, max, cnt + 1);
});
setTimeout(function(){map.setZoom(cnt)}, zoomTimeInterval_ms);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="panel">
<div id="latlong">No latlong Yet</div>
<div id="address">No Address Yet</div>
</div>
<div id="map-canvas"></div>
</body>
</html>
The fact that your map is defined globally isn't relevant if you don't wait until it is initialized before using it.
It is initialized by the initialize function which runs on the body onload event. You use it inline before that happens. This works for me:
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: initialZoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
streetViewControl: false,
zoomControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
google.maps.event.addListenerOnce(map,"zoom_changed", function() {
smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level
});
working example
seems the zoom_changed event doesn't fire when the map initializes, using the "idle" event seems to work:
working example with zoom on idle