2

我正在构建自己的类(用于 SVG 对象)并且最近开始向它添加事件处理。遵循标准模型,我想要这种类型的交互

svgobj.bind('click', function(e){
  // do stuff here on click with svgobj
});

即使我使用 jQuery 来附加事件,这个“绑定”不是 jQuerybind()方法并且 svgobj 不是 jQuery 对象

我遇到的问题是,如果我创建多个对象,那么该svgobj匿名函数内的引用是最后svgobj创建的,而不是触发事件的那个。因此,例如,如果我的事件负责更改对象的状态,则无论我单击哪个对象,只有最后一个对象会更改状态。

我知道这是一个关闭问题,在一位同事的帮助下,我找到了解决方法,但这是一个非常难看的问题。它涉及将函数包装在一个自动执行的匿名函数中,我将正确传递给该svgobj函数并返回原始函数,这是一个示例

svgobj.bind('click', (function(target){
    return function(e){
      // do stuff here on click with target, i.e. the correct svgobj
    }
  })(svgobj)
);

它有效,您可以在此处查看示例http://jsfiddle.net/2late2die/98te2/。您可以通过单击红色/绿色区域来测试拖动事件(通过圆圈部分)和更改状态事件。

有没有更好的方法来解决这个问题?我想避免每次我想对事件做某事时都必须使用两个匿名函数。也许有一种方法可以将自执行函数移动到首先调用事件的方法中,这样“在外部”它仍然看起来像只有一个常规函数作为参数传递?

4

2 回答 2

1

通过使用.bind(我假设 jQuery 是如何使用的),函数this内部成为目标,所以应该不需要在函数内部使用变量。svobj

svgobj.bind('click', function (e) {
  // do stuff here on click with `this` or `$(this)`
});

如果您确实想要一份与当时svgobj完全相同的当前副本.bind,那么您需要在它自己的范围内捕获它以保护它免受更改。您描述为“丑陋”的 lambda 函数方式很可能是实现这一目标的最简单方法。

于 2013-01-23T18:31:37.677 回答
1

你在那里使用了一个非常标准的约定,它会被认为是相当地道的javascript。

如果你真的想让它更干净,你可以像这样拆分匿名函数

function getCallBack(target){
   return function(e){
       //Do stuff with target
   }
}

svobj.bind('click',getCallBack(svobj));

总体而言更长,但它清理了绑定调用,然后您可以添加注释以阐明回调函数的使用。如果您打算重用该代码,也很有用。

更新

由于您似乎正在使用自定义绑定函数,因此您可以通过设置`var that = this;然后that在内部函数内部引用来捕获内部闭包内的原始 this 值。that然后将始终引用调用对象,无论您使用多少级别的内部函数。

但是由于您显然在使用 jQuery,我建议您只使用 jQuery 绑定函数并让您自己轻松使用。

于 2013-01-23T18:28:37.293 回答