如何在循环中绑定click事件?

用循环遍历一组节点绑定click事件,将index作为参数传入,但运行时点击所有节点触发事件时的参数都相同,谁帮忙看下?

下面的代码运行时输出:

Simulator: register click 0 答案1
Simulator: register click 1 答案2
Simulator: register click 2 答案3

但点击对应的按钮时log里的 onItemClicked 都是2,也就是最后一个按钮的事件。

properties: {
    items: [cc.Node],
},
onLoad: function () {
    for (var itemIdx in this.items) {
        var item = this.items[itemIdx];
        cc.log("register click", itemIdx, item.name);

        var button = item.addComponent(cc.Button);
        button.transition = cc.Button.Transition.SCALE;

        item.on('click', function (event) {
            cc.log("target", event.detail.name);
            cc.log("itemIdx", itemIdx);
            this.onItemClicked(itemIdx);
        }, this);
    }

},

onItemClicked: function(idx) {
    cc.log("onItemClicked", idx);
},

我尝试过将事件回调里的

       item.on('click', function (event) {
            cc.log("target", event.detail.name);
            cc.log("itemIdx", itemIdx);
            this.onItemClicked(itemIdx);
        }, this);

换成

        var id = itemIdx;
        item.on('click', function (event) {
            cc.log("target", event.detail.name);
            cc.log("itemIdx", id);
            this.onItemClicked(id);
        }, this);

但是还是一样不对,对js的闭包机制不太懂。。。

Js的基础知识。点击事件是异步操作,itemIdx已经变成了循环结束后的最终值 也就是为什么你这里所有的操作都是2的原因

我知道点击是异步事件。
我在回调注册之前加了一句var id = itemIdx,在lua里会为每个item的回调都保存一个upvalue,值为绑定时的itemIdx,这样点击回调时就会取到这个id的值,但在js里这种写法好像只是创建了一个itemIdx的引用,值还是循环结束后的值。
请问js里如何达到lua里的效果?

var 改成 let

http://mp.weixin.qq.com/s?__biz=MzIxODEyNzM2MQ==&mid=2247483718&idx=1&sn=dbd5fc96d9a4ea5851d4570c5fbf3311&chksm=97ee0c28a099853e745ff67a098d5f245c6e2af81e4e89cb4bf0d13f78b2337e3cb41fdbd650&mpshare=1&scene=23&srcid=1124yVVQIX78ie7xk50rPnYQ#rd

这个是变量的作用域问题,let关键字是es6的用法,如果你要用的话最好看你的项目面向的目标。

谢谢,改成let就好了~

看了下lua和js闭包的区别,js闭包好像无法捕捉函数外的变量,只能用一个function包起来,像这样:

        var self = this;
        (function () {
            var idx = itemIdx;
            item.on('click', function (event) {
                var target = event.detail.node;
                self.onItemClicked(idx);
            }, this);
        })();

可以的,看上面我发的那个连接,对闭包使用的介绍。

对,看到了这种写法,我后来就照这个改的,不过这个本质上还是通过参数把值拷贝到函数内部,并不像lua一样直接可以用函数外部的变量,感觉lua的闭包用起来更方便一些。

在Creator里所有都会转到es5

其实这个问题跟闭包没关系,跟lua的区别在于,js的for循环没有作用于,所有的闭包用的是一个外部引用变量。

了解,确实是作用域不同的区别,只用过lua,不知道js只有function作用域。