I have a google map that I am populating with real estate listings from a database. I have set it up to refresh the listings when the map is panned or zoomed. I am using the dragend & zoom_changed events to accomplish this so that it is not automatically triggered when the map shifts to open an infowindow. I have also added a list of the properties to the side which, when hovered, will open the corresponding marker's infowindow. Finally I have added a click event to the markers to also open the infowindow.
The problem I am having is that when I have the mouse over the map, it always shows the "ready to drag" hand cursor and I have to click on a pin to have it switch to the pointer and then click it a second time to actually open the infowindow. Marker mouseenter and mouseout events do not even register for the same reason. I have tried turning off listeners and different effects, but nothing seems to get rid of whatever it is that the mouse is interacting with by default on the map.
I am at a loss as to what the issue is. Relevant javascript below. You can see the site at http://staging.obs.jacksonholehost.com/properties/.
I have noticed that sometimes when hovering over the map, a marker title will appear for a marker that I am not hovering over. In fact it appears when I am not hovering over any marker. It seems like until I click the map the first time the map goes not know where the markers are located?
I have also noticed that this issue does not seem to impact touch devices, at least not iOS devices, they behave as expected. It seems to be related to the ability to drag the map. It seems like I need to click once to get out of the default drag mode and then a second time to activate a click event.
I have now also noticed that this seems to be an intermittent problem. Sometimes I can get the click events to fire with 1 click and sometimes it takes 2.
function addMapMarkers(map, bounds, markers, alternateMarkers, markersIcon, infowindow ) {
jQuery('.property-details','#property-list').each(function() {
var infowindowWidth = parseInt(jQuery('#map-settings').data('infowindow-width'));
//var iconHeight = parseInt(jQuery('#map-settings').data('icon-height'));
//var iconWidth = parseInt(jQuery('#map-settings').data('icon-width'));
var $this = jQuery(this);
if($this.data('latitude') === '') {return;}
var contentString = $this.find('.infowindow-contents').html();
var markerLatLng = new google.maps.LatLng($this.data('latitude'), $this.data('longitude'));
var image = {
url: $this.data('marker-icon'),
scaledSize: new google.maps.Size(parseInt($this.data('marker-icon-width')),parseInt($this.data('marker-icon-height'))),
};
//var image = customIcon($this.data('count'), 1, $this.data('marker-icon'), iconHeight, iconWidth, iconHeight, iconWidth, 10, 7, 7);
var altImage = {
url: $this.data('marker-icon-alt'),
scaledSize: new google.maps.Size(parseInt($this.data('marker-icon-alt-width')),parseInt($this.data('marker-icon-alt-height'))),
};
//var altImage = customIcon($this.data('count'), 1, $this.data('marker-icon-alt'), iconHeight, iconWidth, iconHeight, iconWidth, 10, 7, 7);
var marker = new google.maps.Marker({
position: markerLatLng,
map: map,
title : $this.data('pin-title'),
brief: jQuery(this).children(".marker_brief").text(),
icon: image
});
google.maps.event.addListener(marker, 'click', function() {
contentString = contentString.replace(/(<span class="src">([^<]+)<\/span>)/gi, '<img src="$2" style="max-width:100%;max-height:100%">');
infowindow.setContent('<div class="mls-map-infowindow-content">' + contentString + '</div>');
var re = /data-mlsid="([^"]+)"/;
var m;
if ((m = re.exec(contentString)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
}
var mlsid = m[1];
jQuery('#map-view').scrollTop(0);
var pos = jQuery('#map-view').find('#' + mlsid).position().top;
jQuery('#map-view').scrollTop(pos);
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'zindex_changed', function() {
contentString = contentString.replace(/(<span class="src">([^<]+)<\/span>)/gi, '<img src="$2" style="max-width:100%;max-height:100%">');
infowindow.setContent('<div class="mls-map-infowindow-content">' + contentString + '</div>');
infowindow.open(map, marker);
});
markers.push(marker);
markersIcon.push(image);
alternateMarkers.push(altImage);
//add to bounds for auto center and zoom
bounds.extend(markerLatLng);
});
}
function clearMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
jQuery(function( $ ){
var map,
infowindow = new google.maps.InfoWindow(),
bounds = new google.maps.LatLngBounds(),
markers=[],
alternateMarkers=[],
markersIcon=[];
var center;
//googleMapTester();/>/first check for bounds set in url
var mlscrit = window.location.pathname;
var ne = '';
var re = /\/\(([^\/]+)\)-ne/;
var m;
if ((m = re.exec(mlscrit)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
ne = m[1];
ne = ne.split(',');
}
//console.log(ne);
var sw = '';
re = /\/\(([^\/]+)\)-sw/;
if ((m = re.exec(mlscrit)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
sw = m[1];
sw = sw.split(',');
}
var scrollwheel = $('#map-settings').data('scrollwheel');
scrollwheel = scrollwheel === "true";
var maptype = $('#map-settings').data('maptypeid'); //google.maps.MapTypeId.
var mapzoom = $('#map-settings').data('zoom');
if(mapzoom !== '' && $.isArray(ne) === false) {
mapzoom = parseInt(mapzoom);
}
else {
mapzoom = 0;
}
var map_options = {
zoom: mapzoom
};
if(maptype === 'ROADMAP') {
map_options.mapTypeId = google.maps.MapTypeId.ROADMAP;
}
else if(maptype === 'SATELLITE') {
map_options.mapTypeId = google.maps.MapTypeId.SATELLITE;
}
else if(maptype === 'HYBRID') {
map_options.mapTypeId = google.maps.MapTypeId.HYBRID;
}
else if(maptype === 'TERRAIN') {
map_options.mapTypeId = google.maps.MapTypeId.TERRAIN;
}
if(typeof scrollwheel !== 'undefined') {
map_options.scrollwheel = scrollwheel;
}
map = new google.maps.Map(document.getElementById('map'), map_options);
if(ne === 'undefined' || ne === '') {
center = $('#map-settings').data('map-center');
if(typeof center !== 'undefined' && center !== '') {
center = center.split(',');
var lat = parseFloat(center[0]);
var lng = parseFloat(center[1]);
var mapCenter = new google.maps.LatLng(lat,lng);
map.setCenter(mapCenter);
}
}
else {
var myLatLng = new google.maps.LatLng(parseFloat(ne[0]),parseFloat(ne[1]));
bounds.extend(myLatLng);
myLatLng = new google.maps.LatLng(parseFloat(sw[0]),parseFloat(sw[1]));
bounds.extend(myLatLng);
}
if(mapzoom === '' || mapzoom === 0 || mapzoom === 'undefined') {
//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);
}
var markerZindex;
$("#property-list").on('mouseenter', '.property-details', function(){
var id=$(this).data('count');
markerZindex = markers[id].getZIndex();
markers[id].setZIndex(1000);
markers[id].setIcon(alternateMarkers[id]);
//google.maps.event.trigger(markers[id], 'dblclick');
}).on('mouseleave', '.property-details', function(){
var id=$(this).data('count');
markers[id].setIcon(markersIcon[id]);
markers[id].setZIndex(markerZindex);
});
$(window).on('resize', function(){
google.maps.event.trigger(map, "resize");
google.maps.event.trigger(map, 'dragend');
});
//var viewportBox;
//var mls_property_count = $('.mls-property-count').first().text();
$('form.fls-mls-property-search').append('<input type="hidden" name="northeast" id="northeast" /><input type="hidden" name="southwest" id="southwest"/>');
var firing = false;
google.maps.event.addListener(map, 'dragend', function() {
//$('.main-content-container').on('click','#refresh-map, #loading-map', function(){
if(firing === true) { return; }
firing = true;
bounds = map.getBounds();
//console.log('fired');
if(typeof bounds !== 'undefined') {
var n,s,e,w;
if($('#map').is(':visible')) {
var ne = bounds.getNorthEast();
$('#northeast').val(ne);
var sw = bounds.getSouthWest();
$('#southwest').val(sw);
n = ne.lat();
s = sw.lat();
e = ne.lng();
w = sw.lng();
}
else {
n = 0;
s = 0;
e = 0;
w = 0;
}
var sort = $('#mls-listing-sort-by').val();
mlscrit = window.location.pathname;
$('.loading-map').removeClass('hidden');
$.ajax({
type: 'POST',
url: ajaxparams.ajaxurl,
data: {
'action': 'fls_mls_get_map_properties',
'data': [n, s, e, w, sort, mlscrit],
},
success: function(response){
//console.log(response);
if(response !== '' && response.success === true && response.data !== "[]" ) {
//console.log(response.data);
var properties = response.data;
clearMarkers(map, markers);
markers=[];
alternateMarkers=[];
markersIcon=[];
$('#property-list').empty();
$.each(properties, function(index, value){
$('#property-list').append(value);
});
addMapMarkers(map, bounds, markers, alternateMarkers, markersIcon, infowindow );
$('.property-stats','.fls-options-top').empty().html('Showing '+ properties.length + ' properties').removeClass('hidden');
contentHeight = $("#property-list","#map-view").outerHeight();
}
else {
console.log(response);
}
},
complete: function() {
$('.loading-map').addClass('hidden');
//$('#refresh-map').remove();
firing = false;
}
});
}
});
google.maps.event.addListener(map, 'tilesloaded', function() {
if($('#mls_area').val() !== '') {
//console.log('tilesloaded trigger');
$('#mls_area').trigger('change');
}
else {
//console.log('normal tilesloaded');
google.maps.event.trigger(this, 'dragend');
}
//$('#loading-map').click();
google.maps.event.clearListeners(map, 'tilesloaded');
});
google.maps.event.addListener(map, 'zoom_changed', function() {
setTimeout(function() {
google.maps.event.trigger(map, 'dragend');
}, 200);
});
});