如何在d3.js中的函数之间共享范围?

时间:2012-05-15 21:14:20

标签: javascript d3.js

我不确定这是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()共享相同的事件监听器功能是有意义的,因为点击一个也应该更新另一个,但我不知道如何解决变量范围问题。

1 个答案:

答案 0 :(得分:1)

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

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,因为这不是向处理程序注册的函数。