kinetic.js循环中的多个单击事件,但只记录最后一个

时间:2013-01-07 15:42:13

标签: javascript html5 audio canvas kineticjs

我有这段代码:

var load_image = function( src ){
    var img = new Image();
    img.src = src;
    return img;
};

var stage = new Kinetic.Stage({container: 'main', width: 640, height: 480});
var layer = new Kinetic.Layer();

var setup = {
    kick : {
        sound: 'kick',
        image_config : {
            image : load_image( '/images/bass.png' ),
            x : 250,
            y : 50
        }
    },
    snare : {
        sound: 'snare',
        image_config : {
            image : load_image( '/images/snare.png' ),
            x : 220,
            y : 220
        }
    },
    hats : {
        sound: 'hats',
        image_config : {
            image : load_image( '/images/hi-hat.png' ),
            x : 140,
            y : 150
        }
    }
};

var img;

for ( name in setup )
{
    img = new Kinetic.Image( setup[name].image_config );

    img.on('click', function()
    {
        soundManager.play( setup[name].sound );
    });

    img.createImageHitRegion(function()
    {
        layer.drawHit();
    },true);

    layer.add(img);
}

stage.add(layer);

这是问题所在。对于安装对象中的每个属性,我想向其添加一个click事件。 (如上所示)

img.on('click', function()
{
    soundManager.play( setup[name].sound );
});

所以当踢踢时,它会触发踢球声,当点击圈套时会触发小鼓声等等......每个设置属性中的声音属性都会描述应该播放的声音。

问题是,所有点击事件都会触发“帽子”声音。我发现这是因为'hats'属性是设置对象中的最后一个属性。

我做错了什么?是因为回调吗?

如果您访问here,您会看到一个示例。

此外,在该示例中,如果您双击,它只触发一次声音,它应该触发两次!怎么了?

2 个答案:

答案 0 :(得分:2)

我认为就是这样:将var从for循环外部移到for循环内部。因为var img使这个变量在每次循环运行时重新定义,所以它只保留了最后一个设置。

相反,您需要添加一些本地作用域,以便每次循环运行时函数不会重写该变量。 尝试在循环内创建局部变量,如下所示

for ( name in setup )
{
    var newImg = new Kinetic.Image( setup[name].image_config );

    newImg.on('click', function()    
    {
        soundManager.play( setup[name].sound );
    });

    newImg.createImageHitRegion(function()
    {
        layer.drawHit();
    },true);

    layer.add(newImg);
}

答案 1 :(得分:0)

我找到了解决方案。我没有在点击回调事件中引用setup[name].sound,而是将图像名称属性设置为名称,然后使用传递给函数的鼠标事件获取名称,如下所示:

var img;

for ( name in setup )
{
    img = new Kinetic.Image( setup[name].image_config );

    img.attrs.name = name;

    img.on('click', function(i)
    {
        soundManager.play( i.shape.attrs.name );
    });

    img.createImageHitRegion(function()
    {
       layer.drawHit();
    },true);

    layer.add(img);
}