0

我有一个 for 循环遍历可变数量的可拖动元素,为每个元素创建一个停止事件回调。回调函数需要知道它所链接的项目的索引。

我遇到了我认为是闭包的问题:当回调被触发时,传递给回调(_x)的循环迭代器索引变量的状态是循环迭代器索引的最后一个值,而不是值定义回调函数时的迭代器索引。下面的一些咖啡脚本:

for _x in [0..total]
  $(window).ready $(".draggable-#{_x}").draggable
    cursor: 'move'
    handle: ".draggable-image-move-button-#{_x}"
    containment: 'div#banner-builder-preview'
    stop: =>
      alert "x === #{_x}"

在上面的示例中,警报提示将始终打印“x === total+1”而不是“x === 0”、“x === 1”...等。

对于具有停止事件的每个元素,将唯一索引传递给回调的最佳解决方案是什么?我宁愿这样做,而无需求助于另一个 jquery 选择器来从触发回调的任何元素中提取更多数据。

更新:

我现在遇到的另一个问题:我的回调,在 for 循环中,看不到文件中定义的其他函数。我认为这很奇怪,即使定义发生在 for 循环用于创建匿名回调函数之前。

例如:

for _x in [0..total]
  do (_x) ->
    $(window).ready $(".draggable-#{_x}").draggable
      cursor: 'move'
      handle: ".draggable-image-move-button-#{_x}"
      containment: 'div#banner-builder-preview'
      stop: =>
        someFunction _x  # ... this line throws an exception, not defined
        alert "x === #{_x}
4

1 回答 1

1

问题是您的回调:

stop: =>
  alert "x === #{_x}"

所有最终都会引用,但他们在被调用之前_x不会评估。_x到那时,_x就有了价值total + 1。这是一个常见的问题,CoffeeScript 有一个do关键字来帮助:

当使用 JavaScript 循环生成函数时,通常会插入一个闭包包装器,以确保循环变量是封闭的,并且所有生成的函数不只是共享最终值。CoffeeScript 提供了do关键字,它立即调用传递的函数,转发任何参数。

所以你可以这样说:

for _x in [0..total]
  do (_x) ->
    $(window).ready $(".draggable-#{_x}").draggable
      #... as before
于 2013-07-22T22:19:40.320 回答