【问题标题】:How to share scope between functions in d3.js?如何在 d3.js 中的函数之间共享范围?
【发布时间】:2012-05-15 21:14:19
【问题描述】:

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

【问题讨论】:

  • onclick 处理程序真的需要同时访问 x 和 y,还是只想访问其中一个?
  • 两者,除了 x 和 y 还有其他变量,例如 2 个 svg 标签的占位符(一个用于线条,另一个用于条形)

标签: javascript d3.js


【解决方案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,因为那不是向处理程序注册的函数。

【讨论】:

  • 我喜欢。我不知道申请()。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
相关资源
最近更新 更多