我有一个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}
答案 0 :(得分:1)
问题在于你的回调:
stop: =>
alert "x === #{_x}"
最终引用_x
,但在被调用之前,他们不会评估_x
。到发生这种情况时,_x
的值为total + 1
。这是一个常见的问题,CoffeeScript有do
keyword帮助:
当使用JavaScript循环生成函数时,通常会插入一个闭包装,以确保循环变量被关闭,并且所有生成的函数不只是共享最终值。 CoffeeScript提供
do
关键字,它立即调用传递的函数,转发任何参数。
所以你可以这样说:
for _x in [0..total]
do (_x) ->
$(window).ready $(".draggable-#{_x}").draggable
#... as before