2014-10-19 50 views
1

我一直在寻找小时,没有任何东西(包括相关的StackOverflow线程)让我更接近。这个问题似乎很简单,但它显然不是基于我可以找到的信息的缺乏。如何使用Snap.svg为​​单个SVG元素做出唯一的响应?

我正在试图制作一个带Snap.svg的交互式钢琴,您可以在其中点击每个琴键并播放其各自的音符。到目前为止,我已经尝试了两种方法:

方法1: 一个简单的FOR循环,它创建所有rects并添加事件侦听器。

<script> 
    window.onload=init(); 
    var S=Snap(500,100); 
    var w=15; var h=100; 

    function init() { 
    for (i=0;i<10;i++) { 
     S.rect(i*w,0,w,h).attr{(id:i)}.click(console.log(this.id)); 
    } 
    } 
</script> 

'undefined'是我点击时得到的。方法2:我尝试在JS对象中包装SVG元素。

<script> 
    window.onload=init(); 
    S=Snap(500,100); 
    var h=15; var w=100; 
    var notes=['A','B','C',...]; 

    function Key(id, x, note) { 
    this.id=id; 
    this.x=x; 
    this.note=note; 
    this.drawSvg=function() { 
      var keyImg=S.rect(x,0,w,h); 
      keyImg.attr({ ... }); 
      keyImg.click(callback); 
      return keyImg; 
      } 
    var callback=function() { 
      console.log(this.note, "clicked!"); 
      return 0; 
     } 
    }//Key() 

    function init() { 
    var keys=[]; 
    for (i=0;i<10;i++) { 
     keys[i]=new Key(i,i*w,notes[i%12]); 
    } 
    for (j=0;j<keys.length;j++) { 
     keys[j].drawSvg(); 
    } 
    } 
</script> 

这几乎奏效。它正确绘制,但我点击每个键我得到“未定义”点击!“ 。

我知道这是因为callback()中的'this'与Key构造函数中的'this'不一样。

所以我的问题是:如何让callback()函数'知道'它被调用的是什么对象,以便我可以在回调中使用该对象的属性?

任何帮助表示赞赏。谢谢。

回答

1

继承人包括2种方法。在你的第一个例子中,你的括号有错误。

此外,点击处理程序必须采用一个函数作为arg,这样'this'将是正确的。因此,像...

jsfiddle

编辑:我添加了可以使用,从不同的角度2种方法。

r.data('key', new Key(i)); 

将一个对象作为数据元素关联到Snap对象。

r.click(clickHandler.bind(r, key2)); 

将对象绑定到处理程序,因此它作为参数传递。

这是很多。您可以缩短一点,具体取决于哪种方法效果最好。

var w=15; var h=100; 

function altKey(id) { 
    this.id='anotherkeymethod ' + id; 
}; 

function Key(id) { 
    this.id='key' + id; 
}; 

function init() { 
    var r, key2; 

    for (i=0;i<10;i++)  { 
     key2 = new altKey(i); 

     r = S.rect(i*w,0,w,h) 
      .attr({ id:i, fill: 'blue' }); 

     r.data('key', new Key(i));   // Method 1 
     r.click(clickHandler.bind(r, key2)); // Method 2 

    } 
    } 

function clickHandler(myKeyEl) { 
    console.log(this.id, this.data('key'), myKeyEl); 
}; 

init(); 
相关问题