多个Market共用一个InfoWindow

来源:互联网 发布:模糊算法讲解 编辑:程序博客网 时间:2024/05/10 12:34

        最近一个项目是关于GIS(geographical information system )的,学习了一下GoogleMap,过程中碰到不少问题。
       首先:GoogleMap API地址: https://developers.google.com/maps/documentation/javascript/tutorial?hl=zh-CN 去里面看下Demo、API,申请一个Key就可以进行GoogleMap的开发了。
       今天看一下第一个问题:多个Market共用一个InfoWindow
       先看一下最开始的代码:
        var points = [{ Longitude: 110.993487, Latitude: 37.997283 }, { Longitude: 112.769617, Latitude: 38.768677 }, { Longitude: 116.913983, Latitude: 26.944184 },                      { Longitude: 102.360533, Latitude: 38.130595 }, { Longitude: 114.552137, Latitude: 35.675677 }, { Longitude: 112.320119, Latitude: 37.371388 },                      { Longitude: 101.360533, Latitude: 38.130595 }, { Longitude: 104.552137, Latitude: 35.675677 }, { Longitude: 111.320119, Latitude: 37.371388}];        var map;        var markers = [];        var infowindow = new google.maps.InfoWindow({            maxWidth: 240        });        function initialize() {            markers = [];            var myLatlng0 = new google.maps.LatLng(points[0].Latitude, points[0].Longitude);                                   var mapOptions = {                zoom: 4,                center: myLatlng0,                mapTypeId: google.maps.MapTypeId.ROADMAP            }            map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);             for (var i = 0; i < points.length; i++) {                var myLatlng = new google.maps.LatLng(points[i].Latitude, points[i].Longitude);                                            var marker0 = new google.maps.Marker({                    position: myLatlng,                    map: map,                                        title: i.toString()                });                google.maps.event.addListener(marker0, 'click', function () {                    infowindow.setContent(marker0.getTitle());                    infowindow.open(map, marker0);                                    });                           }        }
运行代码,会发现Market都显示出来了,但是click事件却有个问题,就是不管点哪一个Market,InfoWindow都会显示在最后一个Market上面,且显示的内容都是最后一个Market的。
      刚好最近正在看《JavaScript高级程序设计(第2版)》,

好象《JavaScript高级程序设计(第3版)》也出来了。
     仔细检查代码,我分析的原因是:JavaScript 变量的作用域是在 function 内,for  { }  里面定义的变量在  for  { }  以外 function 以内都是可以访问的,包括变量 i 。上面代码 for 循环里定义的变量 marker0 每循环一次只是将变量 marker0 指针的重新指向新创建的对象上,而内存栈里面其实只保存了一个变量 marker0 。

以后写 JavaScript 函数时 第一件事应该就是定义该函数要用到的所有变量。
      于是,将代码改成为
        function initialize() {                      var marker0;            markers = [];            var myLatlng0 = new google.maps.LatLng(points[0].Latitude, points[0].Longitude);                                   var mapOptions = {                zoom: 4,                center: myLatlng0,                mapTypeId: google.maps.MapTypeId.ROADMAP            }            map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);             for (var i = 0; i < points.length; i++) {                myLatlng0 = new google.maps.LatLng(points[i].Latitude, points[i].Longitude);                                            marker0 = new google.maps.Marker({                    position: myLatlng0,                    map: map,                                        title: i.toString()                });                google.maps.event.addListener(marker0, 'click', function () {                    showInfoWindow(marker0);                });                           }        }        function showInfoWindow(marker0) {            infowindow.setContent(marker0.getTitle());            infowindow.open(map, marker0);            }


修改后,再运行代码,发现 bug 依旧。继续修改代码为如下就OK了:
           for (var i = 0; i < points.length; i++) {                myLatlng0 = new google.maps.LatLng(points[i].Latitude, points[i].Longitude);                marker0 = new google.maps.Marker({                    position: myLatlng0,                    map: map,                    title: i.toString()                });                attachEvent(marker0);            }
        function attachEvent(marker0) {            google.maps.event.addListener(marker0, 'click', function () {                                showInfoWindow(marker0);            });        }



最终,我的代码修改成这样的了
        function initialize1() {            markers = [];            var myLatlng0 = new google.maps.LatLng(points[0].Latitude, points[0].Longitude);            var mapOptions = {                zoom: 4,                center: myLatlng0,                mapTypeId: google.maps.MapTypeId.ROADMAP            }            map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);            for (var i = 0; i < points.length; i++) {                createMarker(i);            }        }        function createMarker(i) {            var myLatlng = new google.maps.LatLng(points[i].Latitude, points[i].Longitude);            var marker0 = new google.maps.Marker({                position: myLatlng,                map: map,                title: i.toString()            });            google.maps.event.addListener(marker0, 'click', function () {                showInfoWindow(marker0);            });         }


最后借用书里面的例子说一下 JavaScript 里面参数的传递,先看一下的代码,会弹出什么呢?
        function setName(localPerson) {            localPerson.name = "g_cheng";            localPerson = new Object();            localPerson.name = "the.Cheng";        }        var globalPerson = new Object();        setName(globalPerson);        alert(globalPerson.name);
JavaScript 里面函数的参数都是按值类型进行传递的。引用类型传递的只是一个指针。程序运行到 setName 时,setName 作用域内变量 localPerson 指向的是全局变量 globalPerson 指向的堆中的一个对象,localPerson、globalPerson 指向的是同一个对象,所以执行
            localPerson.name = "g_cheng";
会为堆中的对象添加一个 name 的属性,当执行
            localPerson = new Object();            localPerson.name = "the.Cheng";

只是把 localPerson 指向了新建的对象上,此时 localPerson、globalPerson 分别指向各自的对象。
        啰啰嗦嗦写了这么多,感觉也没什么,只是希望对碰到同类问题的 guys 有点帮助。