Изменение значков маркеров при использовании MarkerClusterer (работает в IE9 и Chrome, не работает в Firefox и более ранних версиях IE) - PullRequest
1 голос
/ 29 августа 2011

У меня есть общедоступный сайт, использующий API GoogleMaps v3 и библиотеку MarkerClusterer. Страница, которая имеет проблему, может быть найдена здесь (http://www.mihomes.com/Find-Your-New-Home/San-Antonio-Homes). Если вы просматриваете эту страницу в IE9 или Chrome, отображаются правильные изображения значков выводов, тогда как в предыдущих версиях IE и Firefox разные (и неверные) значки выводов .

IE9 enter image description here

Firefox 3.6.8 enter image description here

Вот код JavaScript, который генерирует контакты / кластеризацию:

$(function() {
    var dl_grid = new DLGrid(".GMapGrid");
    dl_grid.init();

    var dl_map = new DLMap("#map");
    dl_map.init();

    var markers = dl_grid.CollectMarkerData();
    dl_map.LoadMarkers(markers);
});

var DLIcons = new function() {
    var me = this;

    me.NormalIcon = "/images/GoogleMapsIcons/mi_icon_n.png";
    me.HoverIcon = "/images/GoogleMapsIcons/new_mi_icon_r.png";
    me.ClusterIcon = "/images/GoogleMapsIcons/mi_icon_n.png";
    me.ClusterHoverIcon = "/images/GoogleMapsIcons/new_mi_icon_r.png";
    me.SalesCenterIcon = "/images/GoogleMapsIcons/new_mi_icon_n2.gif";
    me.DesignCenterIcon = "/images/GoogleMapsIcons/mi_dc_n.png";
    me.DesignCenterHoverIcon = "/images/GoogleMapsIcons/mi_dc_r.png";
};

//Used for all functions relating to the table below the map
var DLGrid = function(grid_selector) {
    //Initialize variables
    var me = this;
    me.grid = $(grid_selector);

    //Initialize
    me.init = function() {
        setupTableSorting();
        setupHoverEvents();
        setupZoomButtons();
    };

    //Setup the table sorting
    var setupTableSorting = function() {
        //Init tablesorter plugin
        var sort_options = { headers: { 0: { sorter: false }, 4: { sorter: false} } };
        if (MI_DIVISION_LANDING_TABLE_SORT_OPTIONS != undefined) {
            sort_options = MI_DIVISION_LANDING_TABLE_SORT_OPTIONS;
        }
        me.grid.tablesorter(sort_options);

        //As soon as the user sorts, remove all Community Groups
        me.grid.bind("sortEnd", function() {
            me.grid.find("tr.communityGroup").remove();
            $("tr.groupedCommunity").removeClass("groupedCommunity").addClass("ungroupedCommunity");
            //$("tr.ungroupedCommunity").removeClass("ungroupedCommunity");
            me.grid.trigger("update");
        });
    };

    var highlightRow = function(marker) {
        var markerId = (typeof (marker) == "string") ? marker : marker.jsonData.MarkerID;
        $(me.grid).find("#" + markerId).addClass("highlightedRow");
    };

    // Bind to mouseover/mouseout events and highlight the proper row in the table
    // Trigger mouseover/mouseout events when you hover over a row in the table 
    var setupHoverEvents = function() {
        $(document).bind("MARKER_MOUSEOVER", function(e, marker) {
            $(me.grid).find("tbody tr.highlightedRow").removeClass("highlightedRow");
            if (typeof (marker) != "string" && marker.length != undefined) {
                for (var i = 0; i < marker.length; i++) {
                    highlightRow(marker[i]);
                }
            }
            else {
                highlightRow(marker);
            }
        });
        //        $(document).bind("MULTIPLE_MARKER_MOUSEOVER", function(e, markers) {
        //            $(me.grid).find("tbody tr.highlightedRow").removeClass("highlightedRow");
        //            for (var i = 0; i < markers.length; i++) {
        //                var markerId = (typeof (markers[i]) == "string") ? markers[i] : markers[i].jsonData.MarkerID;
        //                $(me.grid).find("#" + markerId).addClass("highlightedRow");
        //            }
        //        });

        $(me.grid).find("tbody tr").mouseover(function() {
            $(document).trigger("MARKER_MOUSEOVER", [$(this).attr("id")]);
        });
    };

    // The zoom buttons next to each row should zoom to a marker and show it's info window
    var setupZoomButtons = function() {
        $(me.grid).find("tbody tr .zoom_link img").click(function() {
            $(document).trigger("MAP_SHOW_MARKER_POPUP_AND_ZOOM", [$(this).parent().parent().attr("id")]);
        });
    };

    // Collect and parse the JSON data from the hidden 'data' column in the table
    me.CollectMarkerData = function() {
        var markers = [];
        $.each(me.grid.find("tbody tr:not(.communityGroup)"), function(i, row) {

            var dataCell = $(row).children("td.data");
            var rawContent = $(dataCell).text();
            var json_data = {};
            if (rawContent.length > 0) {
                json_data = JSON.parse(rawContent);
            }
            json_data["MarkerID"] = $(row).attr("id");
            markers.push(json_data);
        });
        return markers;
    };
};

//Used for all functions relating to map
var DLMap = function(map_div_selector) {
    //Initialize variables
    var me = this;
    me.mapDivSelector = map_div_selector;
    me.mapObj;

    me.init = function() {
        setupMap();
        bindHoverEvents();
        setupPopupEvents();
        setupDesignCenter();
    };

    //Basic setup of map
    var setupMap = function() {
        me.mapObj = new DLGoogleMap(me.mapDivSelector);
        me.mapObj.init(onMarkerMouseOver, showMarkerPopup);
    };

    // Add an array of markers (from json data) to the map
    me.LoadMarkers = function(markers) {
        $.each(markers, function(i, json_marker) {
            me.mapObj.addMarker(json_marker);
        });
        me.mapObj.fitMapToMarkers();
    };

    var showMarkerPopup = function(markerJson, zoomToLocation) {
        var source = $("#MapMarkerInfoWindow").html();
        var template = Handlebars.compile(source);
        var content = template(markerJson);
        var triggerKey = (zoomToLocation == true) ? "MAP_SHOW_POPUP_AND_ZOOM" : "MAP_SHOW_POPUP";
        $(document).trigger(triggerKey, [content, markerJson.Lat, markerJson.Lng]);
    };

    var onMarkerMouseOver = function(markerJson) {
        $(document).trigger("MARKER_MOUSEOVER", markerJson);
    }

    // Highlight (or unhighlight) a marker when a mouseover/mouseout event is triggered
    var bindHoverEvents = function() {
        $(document).bind("MARKER_MOUSEOVER", function(e, marker) {
            if (typeof (marker) != "string" && marker.length != undefined) {
                marker = marker[0];
            }
            me.mapObj.resetMarkerHighlighting();
            me.mapObj.highlightMarker(marker);
        });
        //        $(document).bind("MULTIPLE_MARKER_MOUSEOVER", function(e, markers) {
        //            me.mapObj.resetMarkerHighlighting();
        //            if (markers[0].cluster != null) {
        //                me.mapObj.highlightCluster(markers[0]
        //            }
        //        });
    };

    var setupPopupEvents = function() {
        $(document).bind("MAP_SHOW_POPUP", function(e, content, lat, lng) {
            me.mapObj.showPopup(content, lat, lng);
        });
        $(document).bind("MAP_SHOW_POPUP_AND_ZOOM", function(e, content, lat, lng) {
            me.mapObj.showPopup(content, lat, lng, true);
        });
        $(document).bind("MAP_SHOW_MARKER_POPUP", function(e, marker) {
            if (typeof (marker) == "string") {
                marker = me.mapObj.findMarkerByID(marker);
            }
            showMarkerPopup(marker.jsonData);
        });
        $(document).bind("MAP_SHOW_MARKER_POPUP_AND_ZOOM", function(e, marker) {
            if (typeof (marker) == "string") {
                marker = me.mapObj.findMarkerByID(marker);
            }
            showMarkerPopup(marker.jsonData, true);
        });
    };

    var setupDesignCenter = function() {
        var jsonText = $.trim($("#DesignCenterData").text());
        if (jsonText.length > 5) {
            var dcJson = JSON.parse(jsonText);
            me.mapObj.addDesignCenterMarker(dcJson);
        }
    };
};

var DLGoogleMap = function(map_div_selector) {
    //Initialize variables
    var me = this;
    me.mapDiv = $(map_div_selector);
    me.gmap;
    me.markers = [];
    me.markerClusterer;
    me.infoWindow;
    me.onMouseOver;
    me.onClick;
    me.ZOOM_TO_LEVEL = 14;
    me.highlightedMarkers = [];
    me.designCenterMarker = null;

    //Extend Google Map Classes
    google.maps.Marker.prototype.jsonData = null;
    google.maps.Marker.prototype.iconImg = null;
    google.maps.Marker.prototype.iconHoverImg = null;

    me.init = function(onMouseOver, onClick) {
        me.onMouseOver = onMouseOver;
        me.onClick = onClick;
        setupMap();
        setupClustering();
        setupDrivingDirectionLinks();
    };

    var setupMap = function() {
        //var latlng = new google.maps.LatLng(40.05, -82.95);
        var myOptions = {
            zoom: 14,
            scrollwheel: false,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
        me.gmap = new google.maps.Map(document.getElementById("map"), myOptions);
        me.infoWindow = new google.maps.InfoWindow();
    };

    var setupDrivingDirectionLinks = function() {
        $("a.gDirectionsLink").live("click", function(e) {
            e.preventDefault();
            $(".gPopupInfo").hide();
            $(".gDrivingDirections").show();
        });
        $("a.gCloseDrivingDirections").live("click", function(e) {
            e.preventDefault();
            $(".gDrivingDirections").hide();
            $(".gPopupInfo").show();
        });
    };

    //Add a single json marker to the map
    me.addMarker = function(jsonMarker) {
        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(jsonMarker.Lat, jsonMarker.Lng),
            title: jsonMarker.Name
        });

        marker.jsonData = jsonMarker;
        if (jsonMarker.HasSalesCenter == "True") {
            marker.iconImg = DLIcons.SalesCenterIcon;
        }
        else {
            marker.iconImg = DLIcons.NormalIcon;
        }
        marker.iconHoverImg = DLIcons.HoverIcon;
        marker.icon = marker.iconImg;
        google.maps.event.addListener(marker, 'click', function() {
            me.onClick(marker.jsonData);
        });
        google.maps.event.addListener(marker, 'mouseover', function() { me.onMouseOver(marker) });
        me.markerClusterer.addMarker(marker);
        me.markers.push(marker);
    };

    //Add an arbitrary marker
    me.addDesignCenterMarker = function(dcJson) {
        me.designCenterMarker = new google.maps.Marker({
            position: new google.maps.LatLng(dcJson.Lat, dcJson.Lng),
            title: "Design Center",
            map: me.gmap
        });
        me.designCenterMarker.jsonData = dcJson;
        me.designCenterMarker.iconImg = DLIcons.DesignCenterIcon;
        me.designCenterMarker.iconHoverImg = DLIcons.DesignCenterHoverIcon;
        me.designCenterMarker.icon = me.designCenterMarker.iconImg;
        google.maps.event.addListener(me.designCenterMarker, 'mouseover', function() {
            me.highlightMarker(me.designCenterMarker);
        });
        google.maps.event.addListener(me.designCenterMarker, 'mouseout', function() {
            me.unHighlightMarker(me.designCenterMarker);
        });
        google.maps.event.addListener(me.designCenterMarker, 'click', function() {
            me.infoWindow.close();
            var source = $("#DesignCenterInfoWindow").html();
            var template = Handlebars.compile(source);
            var content = template(me.designCenterMarker.jsonData);
            me.showPopup(content, me.designCenterMarker.jsonData.Lat, me.designCenterMarker.jsonData.Lng);
        });
    };

    me.resetMarkerHighlighting = function() {
        for (var i = 0; i < me.highlightedMarkers.length; i++) {
            me.unHighlightMarker(me.highlightedMarkers[i]);
        }
        me.highlightedMarkers = [];
    }

    me.highlightMarker = function(m) {
        var marker = (typeof (m) == "string") ? me.findMarkerByID(m) : m;
        if (marker != null) {
            if (marker.cluster == null || (marker.cluster.hasMultipleMarkers() == false)) {
                marker.setIcon(marker.iconHoverImg);
            }
            else {
                highlightCluster(marker.cluster);
            }
            me.highlightedMarkers.push(marker);
        }
    };
    me.unHighlightMarker = function(m) {
        var marker = (typeof (m) == "string") ? me.findMarkerByID(m) : m;
        if (marker != null) {
            if (marker.cluster == null || (marker.cluster.hasMultipleMarkers() == false)) {
                marker.setIcon(marker.iconImg);
            }
            else {
                unHighlightCluster(marker.cluster);
            }
        }
    };
    me.zoomAndShowPopup = function(content, lat, lng) {

    };
    me.showPopup = function(content, lat, lng, zoomToLocation) {
        if (zoomToLocation == true) {
            var adjustedLat = lat - (me.gmap.getZoom() * 0.01);
            me.zoomToLocation(adjustedLat, lng);
        }

        me.infoWindow.setContent(content);
        me.infoWindow.setPosition(new google.maps.LatLng(lat, lng));
        me.infoWindow.open(me.gmap);
    };
    me.zoomToLocation = function(lat, lng) {
        me.gmap.setZoom(me.ZOOM_TO_LEVEL)
        me.gmap.setCenter(new google.maps.LatLng(lat, lng));
    };
    me.fitMapToMarkers = function() {
        me.markerClusterer.fitMapToMarkers();
    };


    //Setup the map 'clustering', so that nearby markers will cluster together to form 1 icon
    var setupClustering = function() {
        Cluster.prototype.iconImg = DLIcons.ClusterIcon;
        Cluster.prototype.iconHoverImg = DLIcons.ClusterHoverIcon;

        var mc_options = {
            gridSize: 15,
            maxZoom: 15,
            zoomOnClick: false,
            styles: [{ url: DLIcons.ClusterIcon, height: 30, width: 20, textColor: "#fff", textSize: 10}],
            showMarkerCount: false,
            onClusterAdded: onClusterAdded
        };
        me.markerClusterer = new MarkerClusterer(me.gmap, [], mc_options);

        //Setup Cluster Info Windows with a list of marker links
        google.maps.event.addListener(me.markerClusterer, 'clusterclick', function(cluster) {
            me.infoWindow.close();
            var source = $("#MapClusterInfoWindow").html();
            var template = Handlebars.compile(source);
            var markers = getClusterJsonMarkers(cluster);
            var data = {
                markers: markers
            };
            var content = template(data);
            $(document).trigger("MAP_SHOW_POPUP", [content, cluster.getCenter().lat(), cluster.getCenter().lng()]);
        });

        //Setup Cluster marker highlighting
        google.maps.event.addListener(me.markerClusterer, 'clustermouseover', function(cluster) {
            me.resetMarkerHighlighting();
            highlightCluster(cluster);
            var cmarkers = cluster.getMarkers();
            $(document).trigger("MARKER_MOUSEOVER", [cmarkers]);
        });

        $(".openMarkerPopup").live("click", function(e) {
            e.preventDefault();
            $(document).trigger("MAP_SHOW_MARKER_POPUP", [$(this).attr("rel")]);
        });
    };

    var onClusterAdded = function(cluster) {
        if (clusterHasSalesCenter(cluster)) {
            cluster.iconImg = DLIcons.SalesCenterIcon;
            cluster.updateIconUrl(cluster.iconImg);
        }
        else {
            cluster.iconImg = DLIcons.ClusterIcon;
        }
    };

    var clusterHasSalesCenter = function(cluster) {
        if ((cluster == undefined) || (cluster.markers_ == undefined)) {
            return false;
        }
        for (var i = 0; i < cluster.markers_.length; i++) {
            if (cluster.markers_[i].jsonData.HasSalesCenter == "True") {
                return true;
            }
        }
        return false;
    };

    var highlightCluster = function(cluster) {
        //me.highlightedMarkers = [];
        //        for (var i = 0; i < cluster.markers_.length; i++) {
        //            me.highlightedMarkers.push(cluster.markers_[i]);
        //        }
        cluster.updateIconUrl(cluster.iconHoverImg);
    };

    var unHighlightCluster = function(cluster) {
        cluster.updateIconUrl(cluster.iconImg);
    };

    var getClusterJsonMarkers = function(cluster) {
        var jsonMarkers = [];
        var gmarkers = cluster.getMarkers();
        for (var i = 0; i < gmarkers.length; i++) {
            jsonMarkers.push(gmarkers[i].jsonData);
        }
        return jsonMarkers;
    };

    // Get a marker on the map given it's MarkerID
    me.findMarkerByID = function(markerId) {
        for (var i = 0; i < me.markers.length; i++) {
            if (me.markers[i].jsonData.MarkerID == markerId) {
                return me.markers[i];
                break;
            }
        }
        return null;
    };
};

Этот веб-сайт создан с использованием .NET Framework 3.5 и ASP.NET WebForms.

Спасибо за помощь.

...