Можно ли перебирать каждый из них в 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
Ответы
Ответ 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", но это только личное предпочтение:)