与 d3 事件绑定

gro*_*sNL 4 javascript svg d3.js

在 d3 中编写事件处理程序时,有没有办法bind直接使用等效项?我bind在文档中的任何地方都没有看到实施或讨论。

目前我正在这样做:

graph = function () {
    var self = this;
    this.svg = d3.select('body').append('svg');
    this.svg.append('svg:rect')
        .style('fill', '#f00')
        .attr('width', 300)
        .attr('height', 300);
    this.svg.on('mousedown', function(){return self.mouseDown.call(this, self);})
}
graph.prototype.mouseDown = function (self) {
    /* 'self' is the instance of graph */
    alert(self.svg);
    /* 'this' is the event */
    alert(d3.mouse(this));
}
var g = new graph();
Run Code Online (Sandbox Code Playgroud)

JSFiddle

这工作正常。然而,在这里使用匿名函数call似乎是不好的做法,因为bind本来可以在常规 DOM 元素上完成此操作(如果我没有使用 d3 选择)。我更喜欢使用 d3 选择而不是针对底层 DOM 元素(为了一致性,因为this.svg已经附加到graph对象)。

由于 d3 的on方法似乎是分配事件侦听器的典型方法,是否还有其他选项可以在此处传递数据?

mee*_*mit 5

这一切都源于这样一个事实,即 d3 依赖于this关键字来指向 DOM 元素——使用this几乎就像另一个传递给处理函数的参数一样。这与this作为对类实例的引用的典型用法“冲突” 。

由于Function.prototype.bind()这只是显式设置this函数调用关键字的一种方法,因此不能解决您的问题。换句话说,如果您需要访问 DOM 元素和类实例,则必须设置一个二级变量,例如self指向这两者之一。

那得是至少部分原因D3自己的类(如d3.svg.axis)不使用prototype类声明的方式,而不是依赖于关闭(如描述在这里)。因此,要么切换到该类声明的样式,要么必须继续按照示例中显示的方式进行操作。您的示例还有这个更惯用的变体,但它仍然与您所拥有的基本相同:

graph = function () {
    this.svg = d3.select('body').append('svg');
    this.svg.on('mousedown', this.mouseDownHandler())
}
graph.prototype.mouseDownHandler = function () {
    /* 'self' is the instance of graph */
    var self = this;
    return function(d, i) {
        /* 'this' is the DOM element */
        alert(d3.mouse(this));

        /* now you can work with both "self" and "this" */
    }
}
var g = new graph();
Run Code Online (Sandbox Code Playgroud)