d3js:带有对象上下文的鼠标悬停(函数指针) [英] d3js: mouseover with object context (function pointer)

查看:200
本文介绍了d3js:带有对象上下文的鼠标悬停(函数指针)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用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元素.在其他几种情况下(例如在attrstyle方法内部),它也会执行相同的操作.这被认为是d3的有用功能,因为它为您结合了html元素及其关联的数据.正如您所发现的,这确实意味着,当您将d3方法的类实例方法传递给this冲突时,这部分地就是为什么您通常不使用这种类型的类构造方式看到d3实例的原因(即使用prototypethis).

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).

此外,如果您在很多地方都使用这种样式,则过一会儿就会变得乏味.如果是这样,您可以考虑改用其他方式定义类-无需依赖prototypethis.最自然的是,您可能希望以实现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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆