20

Can someone tell me what is wrong with my code, especially the "Full screen event" part. Thanks!

JSLint says "Functions declared within loops referencing an outer scoped variable may lead to confusing semantics."

function initialize() {
    var mapProp = {
        center: new google.maps.LatLng(45.502808, -73.571486),
    };
    var map = [];
    map[0] = new google.maps.Map(document.getElementById("map1"), mapProp);
    map[1] = new google.maps.Map(document.getElementById("map2"), mapProp);
    map[2] = new google.maps.Map(document.getElementById("map3"), mapProp);

    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[0], title: 'Sunnyvale '
    });
    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[1], title: 'Sunnyvale '
    });
    new google.maps.Marker({
        position: new google.maps.LatLng(45.502808, -73.571486),
        map: map[2], title: 'Sunnyvale '
    });


    google.maps.event.addDomListener(window, "resize", function () {
        for (i = 0; i < 3; i++) {
            var center = map[i].getCenter();
            /*var bounds = map[i].getBounds();*/
            var zoom = map[i].getZoom();
            google.maps.event.trigger(map[i], "resize");
            /*map[i].fitBounds(bounds);*/
            map[i].setCenter(center);
            google.maps.event.addListenerOnce(map[i], 'bounds_changed', function(event) {
                this.setZoom(zoom);
            });
        }

    });

    /** Full Screen event */

    for (i = 0; i < 3; i++) {
        var centerChanged = [];
        var zoomChanged = [];
        google.maps.event.addListener(map[i], 'center_changed', function() {

            var centerChanged[i] = map[i].getCenter();
            var zoomChanged[i] = map[i].getZoom();
        });
        $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {
            map[i].setCenter(centerChanged[i]);
            google.maps.event.addListenerOnce(map[i], 'bounds_changed', function (event) {
                this.setZoom(zoomChanged[i]);
            });
        });
    }

}
google.maps.event.addDomListener(window, 'load', initialize);

JSLint says "Functions declared within loops referencing an outer scoped variable may lead to confusing semantics."

Emilio
  • 1,314
  • 2
  • 15
  • 39
  • 1
    Both your for loops are calling asyc functions. This means the for loops vars are going to be unpredictable inside the callbacks. If your using modern JavaScript easy solution would be change var to let. If you can't use let, you could use a closure to capture the loop vars. – Keith Sep 03 '17 at 19:55
  • @Keith I have hard times using closures correctly, could you help me with that? – Emilio Sep 03 '17 at 19:57
  • 1
    See also [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Felix Kling Sep 03 '17 at 20:24

2 Answers2

28

In your loop, i starts at 0 and iterates until it's equal to 3. That means that whenever you access i after the loop has finished running (for example, in a listener function) it will be equal to 3. You can see this in the following code:

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

That will print all 5s because the function is being called after the loop has finished iterating.

Edit: To fix the issue, you can use javascript's hip new declaration statements: let and const. They exist only in the scope that they are declared, and their values are therefore not overwritten.

for(var i = 0; i < 5; i++) {
    const j = i;
    setTimeout(function() {
        console.log(j);
    }, 1000);
}

Edit 2: Replacing var i with let i appears to work as well:

for(let i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

Edit 3: If es6 isn't an option, you could bind i's value to the function:

for(var i = 0; i < 5; i++) {
    setTimeout((function(j) {
        console.log(j);
    }).bind(null, i), 1000);
}
EKW
  • 2,059
  • 14
  • 24
0

In your loop, you are not declaring the i variable with var, thereby implicitly creating this variable in the global scope.

Jorge Valle
  • 637
  • 5
  • 7