15

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

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()

是否可以在咖啡脚本中做类似的事情,但是使用数组,例如

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

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

更新

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

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

2 回答 2

26

当然有可能:

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()

(正如@epidemian 指出的那样, do ->IIFE 是必要的,以使每个都保持在范围内)target

于 2012-07-07T01:21:40.257 回答
3

你可以toggle循环调用,但你必须注意奇怪的 JS 范围规则。基本上,如果您在循环中生成一个函数,如下所示:

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

您会注意到所有按钮在按下时都会打印“you clicked 3”。这是因为n变量的作用域不仅限于循环体,还包括包含该循环的所有函数。因此,当循环运行时,它的值n被改变,它的最终值是 3。由于循环内创建的所有函数都引用了同一个变量n,所以在循环完成后执行时它们都将打印 3。在 CoffeeScript 中,你可以使用 a 来规避这个问题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 答案的改编):

$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”值作为前缀的约定,但这只是个人喜好:)

于 2012-07-07T02:37:38.107 回答