简体   繁体   中英

How do I add same event listener to many markers and then differentiate between the markers in the listeners in Google Maps API v3?

I have the same event listener for many markers in my Javascript. How do I differentiate between different markers in this listener? I want to display another marker elsewhere on clicking of a particular marker. Every marker has another marker which I display on clicking on it.

The event listener code:

google.maps.event.addListener(marker, 'click', function() {
//code goes here

});

More detail:

I have two arrays markers1 and markers2 each having 10 markers. I display the 10 from markers1 on my map. On clicking markers1[0] marker I want to display the markers2[0] marker on the map. How do I know in the event listener that I have clicked on markers1[0] , now I know that I can use the THIS for identifying markers1[0] but how do I know in the listener that it was the marker at the position 0 in array markers1 so that I could also display marker at position 0 in array markers2 ?

You don't actually have the same listener for each marker, or at least not the same handler function; you just have the same code.

In JavaScript, functions are first-class objects, and in all the answers posted so far, a separate function is being created for each marker. This is a waste of memory.

Here's what I think you want:

var myMarkerClickHandler = function() {
    // use the keyword 'this' to access the marker that got clicked
    console.debug('Marker for ' + this.arrDestination.title + ' got clicked!');
    console.debug('Its position is ' + this.position);
}

for (i = 0; i < arrDestinations.length; i++) {
    // create a marker
    var marker = new google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(arrDestinations[i].lat, arrDestinations[i].lon),
        // as @john-black says, you can add whatever properties you like to the marker
        arrDestination: arrDestinations[i]
    });

    // add *the* event handler to this marker
    google.maps.event.addListener(marker, 'click', myMarkerClickHandler);
}

You can easily add the index (or any other information) to each Marker:

for( var i = 0; i < arrDestinations; i += 1 ) {
    var marker = new google.maps.Marker({
        title: arrDestinations[i].title,
        position: new google.maps.LatLng(arrDestinations[i].lat, arrDestinations[i].lon),
        map: map,
        myIndex: i    // ADDED FIELD: Each marker contains its index
    )};
    bindInfoWindow(marker,map,infowindow,"<p>arrDestinations[i].description + "</p>");
}

Then in your event handler you can do this:

google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(html);
    infowindow.open(map, marker);
    setVisibility(marker);  // ADDED
});

The setVisibility function would be similar to the one suggested by 150PoundsOfDonamite above, except that you know the index of the marker that you want to make visible:

function setVisible(marker) {
    for(var i=0; i<markers1.length; i++) {
        if(i==marker.myIndex) {
            markers2[i].setVisible(true);
        } else {
            markers2[i].setVisible(false);
        }
    }
}

Do you mean that the marker variable is an array of markers? Or do you mean that the code you have is duplicated for each marker? Because if the latter is the case, then in each call to addListener, this refers to the marker in question.

Update after comments

Ok, then you can use a function that just loops through your marker1 :

function setVisible(marker) {
    for(var i=0; i<markers1.length; i++) {
        if(marker==markers1[i]) {
            markers2[i].setVisible(true);
        } else {
            markers2[i].setVisible(false);
        }
    }
}   

Then each individual click listener definition will look like this:

google.maps.event.addListener(marker, 'click', function() {
    setVisible(this);
});

However, you don't want to do something like that 10 times, so you need to put it in a pattern like this:

for(var i=0; i<marker1Data.length; i++) {
    marker = new google.maps.Marker({
        map: theMap,
        position: marker1Data[i].latLng,
        visible: true
    })

    marker1.push(marker);

    google.maps.event.addListener(marker, 'click', (function(marker) {
        return function() {
            setVisible(marker);
        }
    })(marker));
}

Where marker1Data is just an array of LatLng objects that define the location of each marker in marker1 . And of course a for loop for marker2 , but with visible: false .

What you can do is have an external function which handles the adding of markers/infowindows (see 150PoundsOfDonamite's comment). Coincidentally I wrote a blog post today that shows how to do this.

<script type="text/javascript">
function initialize() {
    var i;
    var arrDestinations = [
        {
            lat: 50.815155,
            lon: -0.137072,
            title: "Brighton Pier",
            description: "Brighton Palace Pier dates to 1899"
        },
        {
            lat: 50.822638,
            lon: -0.137361,
            title: "Brighton Pavilion",
            description: "The Pavilion was built for the Prince of Wales in 1787"
        },
        {
            lat: 50.821226,
            lon: -0.139372,
            title: "English's",
            description: "English's Seafood Restaurant and Oyster Bar"
        }
    ];

    var myOptions = {
        zoom: 15,
        center: new google.maps.LatLng(50.820645,-0.137376),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    var infowindow =  new google.maps.InfoWindow({
        content: ''
    });

    // loop over our array
    for (i = 0; i < arrDestinations.length; i++) {
        // create a marker
        var marker = new google.maps.Marker({
            title: arrDestinations[i].title,
            position: new google.maps.LatLng(arrDestinations[i].lat, arrDestinations[i].lon),
            map: map
        });

        // add an event listener for this marker
        bindInfoWindow(marker, map, infowindow, "<p>" + arrDestinations[i].description + "</p>");
    }
}

function bindInfoWindow(marker, map, infowindow, html) {
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(html);
        infowindow.open(map, marker);
    });
} 

google.maps.event.addDomListener(window, 'load', initialize);
</script>
function yourlistener(usedMarker)
{
    // in the var usedMarker you have the reference to the single marker
}

for(var x=0;x<markers.length;x++)
(function(marker){

   google.maps.event.addListener(marker, 'click',
   function() { yourlistener(marker); });}

)(markers[x]);

something like this? hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM