d3js:带有对象上下文的鼠标悬停(函数指针)

时间:2013-05-20 19:13:15

标签: javascript d3.js

我尝试在JavaScript中编写一个Graph类,我想将其用作我网站上更多图表的基础。我的问题是mousedown-Handler:

该类的Graph构造函数添加了mousedown-Method:

this.test = "hello world!";
this.svg.on("mousedown", this.mousedown);
// this.svg.on("mousedown", Graph.prototype.mousedown); <-- does the same

虽然方法如下:

Graph.prototype.mousedown = function() {
    alert(this.test);
};

现在的问题是,此方法未在Graph上下文中调用,而是引用g.[object SVGAnimatedString]。似乎不会调用实际的方法Graph.prototype.mousedown

有没有办法实现我打算在这里做的事情?

1 个答案:

答案 0 :(得分:4)

这是JavaScript中的一个常见问题,并不是D3独有的(你可以谷歌的东西,如“javascript函数这个对象范围”阅读更多)。具体来说,在这种情况下,d3明确地将this对象(也称为上下文)设置为与mousedown事件关联的html或svg元素。它在其他几种情况下也是如此,例如在attrstyle方法中。这被认为是d3的一个有用功能,因为它结合了html元素及其相关数据。正如您所发现的那样,当您将一个类实例方法传递给d3方法时,这意味着存在this冲突,这部分原因是您通常不会使用这种类构造方式看到d3示例(即使用prototypethis)。

你仍然可以通过将this(Graph的实例)分配给在闭包之外声明的变量来解决它(同样,这是一般的JavaScript技术,而不是d3的东西): / p>

// _this is the instance of your class
_this = this;

// _this inside this closure will continue to point to your Graph instance
this.svg.on("mousedown", function(d, i) { _this.mousedown(d, i) });

请注意,由于这个原因,您将无法再从mousedown方法中访问相关的html / svg元素,如果您不需要它,则可以。否则你必须将它作为第3个参数传递给你的mousedown函数:_this.mousedown(d, i, this)

此外,如果你在很多地方这样做,这种风格会在一段时间后变得乏味。如果是这样,您可以考虑切换为以不同方式定义您的类 - 而不依赖于prototypethis。最自然的是,您可能希望以d3对象的实现方式执行此操作。您可以通过查看d3源代码获取更多信息(查找d3.svg.axis这样的示例)。