我尝试在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
。
有没有办法实现我打算在这里做的事情?
答案 0 :(得分:4)
这是JavaScript中的一个常见问题,并不是D3独有的(你可以谷歌的东西,如“javascript函数这个对象范围”阅读更多)。具体来说,在这种情况下,d3明确地将this
对象(也称为上下文)设置为与mousedown事件关联的html或svg元素。它在其他几种情况下也是如此,例如在attr
和style
方法中。这被认为是d3的一个有用功能,因为它结合了html元素及其相关数据。正如您所发现的那样,当您将一个类实例方法传递给d3方法时,这意味着存在this
冲突,这部分原因是您通常不会使用这种类构造方式看到d3示例(即使用prototype
和this
)。
你仍然可以通过将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)
。
此外,如果你在很多地方这样做,这种风格会在一段时间后变得乏味。如果是这样,您可以考虑切换为以不同方式定义您的类 - 而不依赖于prototype
和this
。最自然的是,您可能希望以d3对象的实现方式执行此操作。您可以通过查看d3源代码获取更多信息(查找d3.svg.axis
这样的示例)。