手把手教你为百度地图的多个覆盖物(每个覆盖物拥有各自的参数),绑定事件处理函数

百度地图的覆盖物有很多种,比如点、折线等等。项目要求在地图上划出多个折线,并需要对这些折线绑定事件处理函数(弹出一个信息窗口)。

折线与信息窗口的定义代码如下:

var DeniroMap = {
        lines: [],//存储已创建好的折线对象数组

        //折线样式
        lineStyle: {strokeColor: "blue", strokeWeight: 6, strokeOpacity: 0.5},
        /**
         * 新增折线
         * @param map
         * @param coordinate 坐标
         */
        addLine: function (map, coordinate) {
            var line = new BMap.Polyline([
                new BMap.Point(coordinate.x1, coordinate.x2),
                new BMap.Point(coordinate.y1, coordinate.y2)
            ]);


            map.addOverlay(line, this.lineStyle);
            this.lines.push(line);
        },
        //信息窗口配置
        infoWindowCfg: {
            width: 200,//宽度
            height: 100,//高度
            title: "deniro"//标题
        }
    };

接下来创建了两个折线:

//创建两个折线
    DeniroMap.addLine(map, {
        x1: 116.399,
        x2: 39.910,
        y1: 116.405,
        y2: 39.920
    });

    DeniroMap.addLine(map, {
        x1: 116.300,
        x2: 39.900,
        y1: 116.400,
        y2: 39.900
    });

这里特意画了两个离得比较近的折线,这样方便调试:

现在开始为多条折线绑定事件吧:

    //开始绑定
    var i, line, index, length = DeniroMap.lines.length;
    var indexArray = [1, 2];//假定要传递给每个覆盖物的参数

    //错误的绑定
    for (i = 0; i < length; i++) {
        line = DeniroMap.lines[i];
        index = indexArray[i];
        line.addEventListener("click", function(event){
            var infoWindow = new BMap.InfoWindow(index + "", DeniroMap.infoWindowCfg);
            map.openInfoWindow(infoWindow, event.point);
        });
    }

运行时发现,点击每一个折线,居然都是返回 2!我们希望的是第一条折线返回的是 1,第二条折线返回的是 2。到底哪里出了问题?

原来是闭包惹的祸!这些折线的 click 事件函数,它们的作用域链中引用的都是同一个变量 index。所以我们不管点击哪一条折线,最后看到的都是 2。

解决办法是:在内部创建另一个匿名函数让闭包行为符合我们的预期:

    //正确的绑定
    for (i = 0; i < length; i++) {
        line = DeniroMap.lines[i];
        index = indexArray[i];
        var clickFunction = function (i) {
            return function (event) {
                var infoWindow = new BMap.InfoWindow(i + "", DeniroMap.infoWindowCfg);
                map.openInfoWindow(infoWindow, event.point);
            };
        }(index);

        line.addEventListener("click", clickFunction);
    }

在调用每一个匿名函数时,我们传入了变量 index。因为函数的参数是按值传递的,所以会将变量 index 的当前值复制给内部的 i。在这个匿名函数内部,我们创建并返回了 click 函数,这个函数在内部访问了 i 的闭包。因为 openInfoWindow 方法需要 event 对象,所以我们把 event 作为 click 函数的参数传入了这个最内部的匿名函数咯。

问题解决啦,是不是很开心呀O(∩_∩)O~

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值