Подтвердить что ты не робот

Можно ли перебирать каждый из них в coffeescript?

Я пытаюсь программно создать несколько кнопок 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()

Можно ли сделать что-то подобное в coffeescript, но с массивами, например.

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

Можно ли выполнить цикл и создать переключатель для каждого типа тега?

UPDATE

Да, это возможно. Используйте форму:

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

Ответ 1

Конечно, возможно:

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)

Ответ 2

Вы можете вызвать toggle в цикле, но вы должны знать о странных правилах определения JS. В принципе, если вы создаете функцию внутри цикла, например:

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

Вы заметите, что все кнопки печатают "вы нажали 3" при нажатии. Это потому, что область действия переменной 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]

С учетом этого вы можете реализовать свой цикл так (это адаптация Рикардо ответ):

$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", но это только личное предпочтение:)