1

我不确定这是 d3.js 问题还是 javascript 可见性问题。我有两个函数将相同的事件侦听器分配给不同的节点:

function render_line(){
    var x = d3.scale.ordinal();
    ...

    d3.select("#my_line").on("click", onclick);
}

function render_bar(){
    var y= d3.scale.linear();
    ...

    d3.select("#my_bar").on("click", onclick);
}

function onclick(d,i){
    use(x,y) // error: can't access x or y
    ...
}

我认为共享相同的事件侦听器函数对两者都很有意义,render_line()因为render_bar()单击一个也应该更新另一个,但我不知道如何解决变量范围问题。

4

1 回答 1

1

如果您在函数之外声明变量然后分配给它们(不使用var函数中的关键字),那么您的函数将是闭包,被授予从这些变量中设置和获取值的访问权限。

var x,y;
function foo(){
  x = d3.scale.ordinal();
  d3.select("...").on("click",onclick);
}
function bar(){
  y = d3.scale.linear();
  d3.select("...").on("click",onclick);
}
function onclick(){
  // has access to both x and y here
}

或者,如果这感觉太脏,那么在事件注册期间围绕局部变量创建一个闭包,将值传递给您的共享函数:

function foo(){
  var x = d3.scale.ordinal();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,x);
  });
}
function foo(){
  var y = d3.scale.linear();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,y);
  });
}
function onclick(evt,scale){
  // Use 'scale' passed in
}

请注意,在这种情况下,您以后不能取消注册onclick,因为那不是向处理程序注册的函数。

于 2012-05-15T21:18:12.457 回答