Problem mit Funktions-Parameter in Schleife

Zerberus777

Mitglied
Hallo,

ich habe mal wieder ein interessantes Problem...
Ich möchte in der Schleife Zeile71-85 Googlemaps-Marker und zugehörige Events initialisieren. Mit den Markern (Zeile72-77) funktioniert es, aber mit den Events (Variante4) nicht: "markierungen[zaehler] is undefined".
Die Varianten 1 bis 3 funktionieren außerhalb der Schleife problemlos, aber nicht in der Schleife (verschiedene Fehlerausgaben, nur ein dargestellter Marker).
Weis Jemand, wo mein Fehler liegt?

Gruß

Zerberus
Code:
<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <title>Marker Animations</title>
  <style>

  html, body {
  height: 100%;
  margin: 0px;
  padding: 0px;
    }
    #map-canvas {width:400px; height:600px}

  </style>
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
   <script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
   
  <script>
var berlin = new google.maps.LatLng(52.520831, 13.409387);
var posberlin1 = new google.maps.LatLng(52.51, 13.40);
var posberlin2 = new google.maps.LatLng(52.52, 13.41);
var posberlin3 = new google.maps.LatLng(52.53, 13.42);
var markberlin1, markberlin2, markberlin3;
var map;
var z1,z2,z3;
z1=1;
z2=2;
z3=3;
var markierungenAnzahl=3;
var markierungen =    [["markerPosition","markerName","bildDiv","Standort"],
           ["posberlin1","markberlin1","berlin1","Standort:<br>Berlin1"],
           ["posberlin2","markberlin2","berlin2","Standort:<br>Berlin2"],
           ["posberlin3","markberlin3","berlin3","Standort:<br>Berlin3"]];

     var boxText = document.createElement("div");
     boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: #FFFFCC; padding: 5px; text-align:center; font-weight:bold; border-radius:5px; box-shadow: 4px 4px 5px #333333";
     boxText.innerHTML = "";

     var myOptions = {
        content: boxText
       ,disableAutoPan: false
       ,maxWidth: 0
       ,pixelOffset: new google.maps.Size(-40, -5)
       ,zIndex: 99
       ,boxStyle: {
        background: "url('tipbox.gif') no-repeat"
        ,opacity: 0.85
        ,width: "80px"
            }
       ,closeBoxMargin: ""
       ,closeBoxURL: ""
       ,infoBoxClearance: new google.maps.Size(1, 1)
       ,isHidden: false
       ,pane: "floatPane"
       ,enableEventPropagation: true
     };

function initialize() {

var zaehler=1;
var mapOptions = {
zoom: 12,
center: berlin,
zoomControl: false,
streetViewControl: false,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.HYBRID
};
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
while (zaehler <= markierungenAnzahl) {
window[markierungen[zaehler][1]] = new google.maps.Marker({
map:map,
draggable:true,
animation: google.maps.Animation.DROP,
position: window[markierungen[zaehler][0]]
});

//* Variante4
google.maps.event.addListener(window[markierungen[zaehler][1]], 'mouseover', function() {toggleBounce(markierungen[zaehler][2],window[markierungen[zaehler][1]],markierungen[zaehler][3])});
google.maps.event.addListener(window[markierungen[zaehler][1]], 'mouseout', function() {toggleBounce(markierungen[zaehler][2],window[markierungen[zaehler][1]])});
//Variante4 Ende */

zaehler++;
}

/* Variante1
google.maps.event.addListener(markberlin1, 'mouseover', function() {toggleBounce("berlin1",markberlin1,"Standort:<br>Berlin1")});
google.maps.event.addListener(markberlin1, 'mouseout', function() {toggleBounce("berlin1",markberlin1)});
google.maps.event.addListener(markberlin2, 'mouseover', function() {toggleBounce("berlin2",markberlin2,"Standort:<br>Berlin2")});
google.maps.event.addListener(markberlin2, 'mouseout', function() {toggleBounce("berlin2",markberlin2)});
google.maps.event.addListener(markberlin3, 'mouseover', function() {toggleBounce("berlin3",markberlin3,"Standort:<br>Berlin3")});
google.maps.event.addListener(markberlin3, 'mouseout', function() {toggleBounce("berlin3",markberlin3)});
//Variante1 Ende */

/* Variante2
google.maps.event.addListener(window[markierungen[1][1]], 'mouseover', function() {toggleBounce(markierungen[1][2],window[markierungen[1][1]],markierungen[1][3])});
google.maps.event.addListener(window[markierungen[1][1]], 'mouseout', function() {toggleBounce(markierungen[1][2],window[markierungen[1][1]])});
google.maps.event.addListener(window[markierungen[2][1]], 'mouseover', function() {toggleBounce(markierungen[2][2],window[markierungen[2][1]],markierungen[2][3])});
google.maps.event.addListener(window[markierungen[2][1]], 'mouseout', function() {toggleBounce(markierungen[2][2],window[markierungen[2][1]])});
google.maps.event.addListener(window[markierungen[3][1]], 'mouseover', function() {toggleBounce(markierungen[3][2],window[markierungen[3][1]],markierungen[3][3])});
google.maps.event.addListener(window[markierungen[3][1]], 'mouseout', function() {toggleBounce(markierungen[3][2],window[markierungen[3][1]])});
//Variante2 Ende */

/* Variante3
google.maps.event.addListener(window[markierungen[z1][1]], 'mouseover', function() {toggleBounce(markierungen[z1][2],window[markierungen[z1][1]],markierungen[z1][3])});
google.maps.event.addListener(window[markierungen[z1][1]], 'mouseout', function() {toggleBounce(markierungen[z1][2],window[markierungen[z1][1]])});
google.maps.event.addListener(window[markierungen[z2][1]], 'mouseover', function() {toggleBounce(markierungen[z2][2],window[markierungen[z2][1]],markierungen[z2][3])});
google.maps.event.addListener(window[markierungen[z2][1]], 'mouseout', function() {toggleBounce(markierungen[z2][2],window[markierungen[z2][1]])});
google.maps.event.addListener(window[markierungen[z3][1]], 'mouseover', function() {toggleBounce(markierungen[z3][2],window[markierungen[z3][1]],markierungen[z3][3])});
google.maps.event.addListener(window[markierungen[z3][1]], 'mouseout', function() {toggleBounce(markierungen[z3][2],window[markierungen[z3][1]])});
//Variante3 Ende */

}

var ib = new InfoBox(myOptions);

function toggleBounce(selectDiv, selectMarker, standort) {

if (selectMarker.getAnimation() != null) {
selectMarker.setAnimation(null);
ib.close(map, selectMarker);
document.getElementById(selectDiv).style.transform="scale(1)";
document.getElementById(selectDiv).style.transition="transform 0.1s";
document.getElementById(selectDiv).style.zIndex="10";
} else {

selectMarker.setAnimation(google.maps.Animation.BOUNCE);
boxText.innerHTML = standort;
ib.open(map, selectMarker);
document.getElementById(selectDiv).style.transform="scale(1.5)";
document.getElementById(selectDiv).style.transition="transform 1s";
document.getElementById(selectDiv).style.zIndex="50";
}
}
google.maps.event.addDomListener(window, 'load', initialize);

  </script>
  </head>
  <body>
   <div id="div-main" style="position:relative;width:1225px;height:700px">
  <div id="map-canvas" style="position:absolute;left:0px"></div>
   <div id="berlin1"  onmouseover="toggleBounce('berlin1',markberlin1,'Standort:<br>Berlin1')" onmouseout="toggleBounce('berlin1',markberlin1)" style="position:absolute;left:400px;width:200px; height:200px; background-color: green;border-style:solid;border-color:black"></div>
   <div id="berlin2"  onmouseover="toggleBounce('berlin2',markberlin2,'Standort:<br>Berlin2')" onmouseout="toggleBounce('berlin2',markberlin2)" style="position:absolute;left:600px;width:200px; height:200px; background-color: green;border-style:solid;border-color:black"></div>
  <div id="berlin3"  onmouseover="toggleBounce('berlin3',markberlin3,'Standort:<br>Berlin3')" onmouseout="toggleBounce('berlin3',markberlin3)" style="position:absolute;left:800px;width:200px; height:200px; background-color: green;border-style:solid;border-color:black"></div>
   </div>
   </body>
</html>
 
Diese Notation
Code:
window[markierungen[zaehler][1]]
ist mir unbekannt und Firebug zeigt "undefined" dafür an.
Ich empfehle, ein weiteres Feld im Array markierungen für das Marker-Objekt anzulegen:
Code:
var markierungen =    [["markerPosition","markerName","bildDiv","Standort", "markerObjekt"],
          [posberlin1,"markberlin1","berlin1","Standort:<br>Berlin1",null],
und das Objekt dort einzutragen:
Code:
while (zaehler <= markierungenAnzahl) {
    markierungen[zaehler][4] = new google.maps.Marker({
Und außerdem muss IMO das posBerlinx bei der Definition des Arrays ohne Hochkommas geschrieben werden, weil Du ja die Variable zuweisen willst und keinen String.
Außerdem finde ich, dass es die Lesbarkeit verbessern würde, wenn Du die Inhalte des Arrays als Objekte anlegen würdest:
Code:
var markierungen =    [
    {markerPosition: posBerlin1,
     markerName: "markBerlin1",
     bildDiv: "berlin1",
     Standort: "Standort:<br>Berlin1",
     markerObjekt: null}, // usw.
// ...
var zaehler = 0;
while (zaehler < markierungen.length) {
    markierungen[zaehler]["markerObjekt"] = new google.maps.Marker({
         map:map,
         draggable:true,
         animation: google.maps.Animation.DROP,
         position: markierungen[zaehler]["markerPosition"]
    }); // usw.
 
Zuletzt bearbeitet:
Uups, ich muss wohl alles zurück nehmen, was ich oben geschrieben habe: Deine Notation mit dem window-Objekt funktioniert ja tatsächlich! Wo hast Du das denn her?!
Damit auch das Registrieren der Listener richtig funktioniert, musst Du es wie folgt ändern:
Code:
//* Variante4
google.maps.event.addListener(window[markierungen[zaehler][1]], 'mouseover',
function (z) { return function () { toggleBounce(markierungen[z][2], window[markierungen[z][1]], markierungen[z][3]) } }(zaehler)
);
google.maps.event.addListener(window[markierungen[zaehler][1]], 'mouseout',
function (z) { return function () { toggleBounce(markierungen[z][2], window[markierungen[z][1]]) } }(zaehler)
);
//Variante4 Ende */
Das ist ein Fehler, der in diesem Zusammenhang häufig auftritt: Die Listener-Funktion wird ja noch nicht beim Registrieren aufgerufen, sondern erst viel später beim Mouseover/-out. Dann ist die Schleife längst durchgelaufen und die Variable zaehler hat den Wert 4, womit es natürlich nicht funktionieren kann.
Bei der korrigierten Version wird die äußere anonyme Funktion (function(z)) sofort aufgerufen, wenn die Schleife durchläuft und innerhalb dieser Funktion hat der Parameter z dann den richtigen Wert 1, 2, 3. Die äußere Funktion gibt die innere als Return-Wert zurück, so dass die innere der wirksame Listener ist.
 
Naja, auch wenn das funktioniert, finde ich, dass es wenig empfehlenswert ist, so etwas zu tricksen. Ich würde den weg vorziehen, den ich in meinem ersten Posting begonnen habe, das ist klarer und besser zu verstehen.
 
Zurück