d3js:带有对象上下文的鼠标悬停(函数指针) [英] d3js: mouseover with object context (function pointer)
问题描述
我试图用JavaScript编写一个Graph
类,该类希望用作我网站上其他图形的基础.我的问题是mousedown-Handler:
I tried to write a Graph
class in JavaScript which I want to use as base for further graphs on my website. My problem is the mousedown-Handler:
该类的Graph
构造函数添加mousedown-Method:
The Graph
constructor of the class adds the 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
的实际方法.
The problem now it, that this method is not called inside the Graph
context, instead, it is a reference to g.[object SVGAnimatedString]
. It seems that not the actual method Graph.prototype.mousedown
gets called.
有什么办法可以实现我打算在这里做什么?
Is there any way to achieve what I intend to do here?
推荐答案
这是JavaScript中的常见问题,并非D3所独有(您可以通过搜索诸如"javascript function this object scope"之类的内容来了解更多信息).特别是在这种情况下,d3将this
对象(又名上下文)显式设置为与mousedown事件关联的html或svg元素.在其他几种情况下(例如在attr
和style
方法内部),它也会执行相同的操作.这被认为是d3的有用功能,因为它为您结合了html元素及其关联的数据.正如您所发现的,这确实意味着,当您将d3方法的类实例方法传递给this
冲突时,这部分地就是为什么您通常不使用这种类型的类构造方式看到d3实例的原因(即使用prototype
和this
).
This is a common problem in JavaScript, not unique to D3 (you can google stuff like "javascript function this object scope" to read more). Specifically in this case, d3 is explicitly setting the this
object (aka context) to be the html or svg element associated with the mousedown event. It does the same thing in several other cases, such as inside the attr
and style
methods. This is considered a useful feature of d3, because it combines for you the html element and its associated data. It does mean, as you've discovered, that there is a this
conflict when you pass into a d3 method a class instance method, which is partially why you don't commonly see d3 examples using this style of class construction (ie making use of prototype
and this
).
但是,仍然可以解决此问题,方法是将this
(Graph的实例)分配给在闭包外部声明的变量(同样,这是一种通用的JavaScript技术,而不是d3):
You can still work around it though, by assigning your this
(the instance of Graph) to a variable declared outside a closure (and again, this is a general JavaScript technique, not a d3 thing):
// _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元素,如果不需要,也可以.否则,您必须将其作为第三个参数传递给mousedown函数:_this.mousedown(d, i, this)
.
Note that as a result of this you'll no longer have access to the associated html/svg element from inside your mousedown method, which is ok if you don't need it. Otherwise you have to pass it in as a 3rd param to your mousedown function: _this.mousedown(d, i, this)
.
此外,如果您在很多地方都使用这种样式,则过一会儿就会变得乏味.如果是这样,您可以考虑改用其他方式定义类-无需依赖prototype
和this
.最自然的是,您可能希望以实现d3对象的方式进行操作.您可以通过查看d3源代码来获取更多信息(对于其中一个示例,请查看d3.svg.axis
.)
Also, this style gets tedious after a while if you're doing it in a lot of places. If so, you might consider switching to defining your classes differently -- without the reliance on prototype
and this
. Most naturally, you may want to do it the way d3 objects are implemented. You can get more info by checking out the d3 source code (look for d3.svg.axis
for one such example).
这篇关于d3js:带有对象上下文的鼠标悬停(函数指针)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!