javascriptangularjsgoogle-mapsjshintgrunt-contrib-jshint

javascript event function being called multiple times


I am integrating maps on a webpage with Overlapping Marker Spiderfier on google maps. I added a click listener on the marker as below.

$scope.setMarkers = function() {
    for (var i = 0; i < $scope.markers.length; i++) {
        $scope.markers[i].setMap($scope.map);
        $scope.oms.addMarker($scope.markers[i]);
        var marker = $scope.markers[i];
        var iw = new google.maps.InfoWindow({
            content: ""
        });
        $scope.oms.addListener('click', function(marker) {
            iw.setContent(marker.desc);
            iw.open($scope.map, marker);
        });
    }
};

and it works fine but jshint is giving me error for making function inside loop. So i changed it to.

$scope.setMarkers = function() {
    for (var i = 0; i < $scope.markers.length; i++) {
        $scope.markers[i].setMap($scope.map);
        $scope.oms.addMarker($scope.markers[i]);
        $scope.addMarkerEventListener(i);
    }
};
$scope.addMarkerEventListener = function(i) {
    var marker = $scope.markers[i];
    var iw = new google.maps.InfoWindow({
        content: ""
    });
    $scope.oms.addListener('click', function(marker) {
        iw.setContent(marker.desc);
        iw.open($scope.map, marker);
    });
};

now when I am clicking on the marker its opening upto 90 info windows one behind another(i have 90 markers in an array). What am i missing.


Solution

  • you add the same listener each time you add a marker(Note that a listener will not overwrite previously added listeners).

    It's sufficient to add 1 listener and to use 1 InfoWindow(except you want to have multiple InfoWindow's open at the same time).

    Your first attempt works as expected because you overwrite iw inside the loop.

    Possible solution:

    //create a single InfoWindow-instance
    $scope.iw = new google.maps.InfoWindow();
    
    //add a single click-listener
    $scope.oms.addListener('click', function (marker) {
        $scope.iw.close();
        $scope.iw.setContent(marker.desc);
        $scope.iw.open($scope.map, marker);       
    });
    
    //the loop
    for (var i = 0; i < $scope.markers.length; ++i) {
        $scope.markers[i].setMap($scope.map);
        $scope.oms.addMarker($scope.markers[i]);
    }
    

    Demo: http://jsfiddle.net/doktormolle/qoko4425/