【问题标题】:Why does event listener callback function only work inside function scope?为什么事件侦听器回调函数只能在函数范围内工作?
【发布时间】:2017-01-21 09:00:25
【问题描述】:

我正在开发一个 D3 项目,该项目使用一个事件侦听器,该侦听器每隔几毫秒调用一次以更新/动画化屏幕上圆圈的位置。

首先调用函数 startForces() 以激活 D3 力,然后我们将其传递给圆圈。

当回调函数(勾选)位于 startForces() 范围之外时,该函数似乎只调用了一次,并且圆圈在页面上显示为静态。 (参见顶部代码块)

但是,当回调函数(勾选)位于 startForces() 的范围内时,一切都按预期工作,并且圆圈显示为动画。 (底部代码块)

我试图理解为什么 javascript 会以这种方式工作。为什么上面的代码不起作用,下面的代码起作用?

TL:DR

不工作的代码

var ticked = function(circles){
   circles.attr('cx', function(d) { return d.x })
   .attr('cy', function(d) { return d.y })
}

var startForces = function(data, circles) {
  simulation.nodes(data)
  .on('tick', ticked(circles))
}

=====

工作代码

    var startForces = function(data, circles) {
      simulation.nodes(data)
      .on('tick', ticked)

    function ticked(){
      circles.attr('cx', function(d) { return d.x })
      .attr('cy', function(d) { return d.y })
    }
   }

为什么不一样?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    其实和函数的位置完全没有关系。

    当你这样做时:

    .on('tick', ticked(circles))

    您在创建on 侦听器时立即调用ticked。然后,将tick 的回调分配为使用圆圈调用ticked结果,即undefined

    当你这样做时:

    .on('tick', ticked)

    您将回调分配为 ticked 函数,这是您想要的。

    【讨论】:

    • 谢谢!把我的头绕在它周围,但它开始变得有意义了。
    • 是的,这会绊倒很多人!请记住 ticked(circles) 的评估值是未定义的,但 ticked 的值是函数本身。您希望将函数分配给回调,而不是其返回值。
    • @Starcat 只是将我的两分钱加到 thedayturns 的答案中:通常,力模拟中的 tick 函数不需要参数。但是,如果出于某种原因确实需要将任何参数传递给它,请将其包装在匿名函数中:on('tick', function(){ ticked(foo)})
    猜你喜欢
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2020-08-08
    • 2020-04-06
    • 2022-08-16
    • 2020-01-18
    相关资源
    最近更新 更多