Skip to content Skip to sidebar Skip to footer

Showing Google Maps Marker Infoname On Mouseover Of A Dynamically Generated Div

I want to introduce a functionality which allows a marker's infoname to appear or disappear upon mouseover or mouseout of a corresponding DIV element generated from jQuery. However

Solution 1:

Currently you've got a variable marker declared local to the process function, but you're trying to read and write to it from other functions. In particular, addMarker writes to marker without var, which causes an accidental global variable to be created. Meanwhile process is not actually writing to the marker local it has declared, so it contains undefined, which will trip the Google Maps code up when you pass that in.

(Tools like jslint, or ECMAScript 5 Strict Mode can catch accidental globals for you. Note total and i are also accidental globals.)

It looks like addMarker and addInfoname have been hacked out of the body of process without tying up the variables from process that both of them used. If they were included in the body of process it would work, but you'd get the described behaviour where the same marker value was used for every div because of the Closure Loop Problem.

This problem occurs in languages with closures and function-level scope, which includes JavaScript, Python and others. In these languages any variables defined by or inside a for loop are local to the containing function, not reallocated every time you go around the loop. So if you make a closure referring to i in the first iteration of the loop, it's the same variable i as you refer to in the second iteration of the loop; every instance of the function has a closure over the same variable i so every function will see the same value. The same would be true of marker.

The Closure Loop Problem can be avoided through use of a second closure that keeps the loop variable in an argument, or, more cleanly, using a closure-based loop mechanism instead of the C-like for loop. ECMAScript 5 offers array.forEach() for this purpose and jQuery offers $.each():

functionprocess(json) {
    $('#results').empty();
    var gev= google.maps.event;
    $.each(json.details, function(detaili, detail) {
        var marker= addMarker(detail.lat, detail.lng);

        $('#results').append($('<div>', {
            text: detail.name,
            mouseover: function() { gev.trigger(marker, 'mouseover'); },
            mouseout: function() { gev.trigger(marker, 'mouseout'); }
        }));

        var infoname= newInfoName();
        gev.addListener(marker, 'mouseover', function() { infoname.show(); });
        gev.addListener(marker, 'mouseout', function() { infoname.hide(); });
        infoname.open(map, marker);
    });
}

functionaddMarker(lat, lng) {
    returnnew google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(lat, lng),
        icon: new google.maps.MarkerImage(
            'images/r.png',
            new google.maps.Size(30, 30),
            new google.maps.Point(0, 0),
            new google.maps.Point(0, 30)
        )
    });
}

Solution 2:

The "a is undefined" error is probably because you are trying to create the map before the dom is ready. At least, that's the only time I have seen it. I can't tell from your code where you're creating it, but make sure that the map div is ready. You either have to place the call to your initialize function at the bottom of the page or in an page load listener. Here's one way you can do that (this can go anywhere in the page):

functioninitialize() {
    var map = new google.maps.Map(document.getElementById("map_canvas"), {
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    google.maps.event.addListener(map, 'idle', function () {
        $.getJSON(query, process);
    });
}
google.maps.event.addDomListener(window, 'load', initialize);

Also notice that your idle listener goes in that init function, too, since it won't be able to run until the map has been created.

If that's not causing the "a is undefined" error, then I can't see it in the code you've posted. I do, however, see some other problems with your code. So maybe that is actually what's causing it. First, the var marker; definition in process doesn't do anything. Here you are creating a local variable, but that local variable never gets defined. Then addMarker you are creating a global variable by defining marker without the var. So the marker in addInfoname always refers to the global marker, which will always be the last marker defined. So that's why the divs are always showing up with the last marker. I would put a return before marker = ... in addMarker, and use it to set the marker variable like this:

var marker = addMarker(detail);

In process, of course. Then you also have to send this to addInfoname as a parameter so it gets the correct one.

Post a Comment for "Showing Google Maps Marker Infoname On Mouseover Of A Dynamically Generated Div"