可以在coffeescript中循环每个?

时间:2012-07-07 01:04:18

标签: jquery loops coffeescript

我正在尝试以编程方式创建一些javascript按钮来切换页面上的可见性(用于snappy标记过滤)。这适用于一个标签:

trigger = ".sales-focus-btn"
target = ".sales-focus"

jQuery ->   
  $(trigger).toggle ->
    $("#primary-content").find('.container').hide()
    $("#primary-content").find(target).show()
  , ->
    $("#primary-content").find('.container').show()

是否可以在coffeescript中执行类似的操作,但使用数组,例如

trigger = [
  ".sales-focus-btn"
  ".service-focus-btn"
  ".other-focus-btn"
  ...
]
target = [
  ...
]

是否可以循环并为每种类型的标签创建一个切换?

更新

是的,这是可能的。使用表格:

myFunction = (el) -> console.log el
myFunction elem for elem in array

2 个答案:

答案 0 :(得分:24)

当然有可能:

content = $('#primary-content')
container = content.find('.container')

tags = [
    '.sales-focus'
    '.service-focus'
    '.other-focus'
]

$.each tags, (tag) ->
    target = content.find(tag)
    $(tag + "-btn").toggle ->
        container.hide()
        target.show()
    , ->
        container.show()

请记住缓存DOM元素。或者,使用for tag in tags代替jQuery.each tags, (tag) -> ...

for tag in tags
    do ->
      target = content.find(tag)
      $(tag + "-btn").toggle ->
        container.hide()
        target.show()
      , ->
        container.show()

do -> IIFE是保持每个target范围的必要条件,正如@epidemian指出的那样)

答案 1 :(得分:3)

您可以在循环中调用toggle,但您必须了解奇怪的JS范围规则。基本上,如果你在循环中生成一个函数,就像这样:

for n in [1, 2, 3]
  $(".btn-#{n}").click -> alert "you clicked #{n}"

您会注意到all the buttons print "you clicked 3" when pressed。那是因为n变量的范围不仅限于循环体,而是包含该循环的所有函数。因此,当循环运行时,n的值被更改,它的最终值为3.由于在循环内创建的所有函数都引用了相同的变量n,因此它们将在执行时全部打印3循环结束后。在CoffeeScript中,您可以使用do statement来解决此问题,这将基本上引入新的块范围变量:

for n in [1, 2, 3]
  do (n) ->
    $(".btn-#{n}").click -> alert "you clicked #{n}"

或使用辅助功能:

setupClick = (n) -> 
  $(".btn-#{n}").click -> alert "you clicked #{n}"

setupClick n for n in [1, 2, 3]

考虑到这一点,你可以像这样实现你的循环(这是Ricardo's answer的改编):

$content = $('#primary-content')
$container = $content.find('.container')

targetsByTrigger =
  '.sales-focus-btn': '.sales-focus'
  '.service-focus-btn': '.service-focus'
  '.other-focus-btn': '.other-focus'

setupTrigger = (trigger, target) ->
  $(trigger).toggle ->
    $container.hide()
    $content.find(target).show()
    console.log 'showing', target
  , ->
    $container.show()

setupTrigger trigger, target for trigger, target of targetsByTrigger

请注意,我将触发器和目标类名都放在一个对象中,因此触发器类名可以来自<target class name>-btn;如果不是这样,那么坚持像['.sales-focus', '.service-focus', '.other-docus']这样的数组然后添加-btn可能会更好。此外,我喜欢使用$作为“jQuerized”值的前缀的惯例,但这只是个人偏好:)