bootstrap のトグルボタンを、coffeescript で扱った時に、罠にはまってしまったので、共有と自戒を込めて書く。
まず、Bootstrap は、トグルボタンを簡単に作ることができる。
<button id="button1" type="button" class="btn btn-primary" data-toggle="button" aria-pressed="false" autocomplete="off">
Single toggle
</button>
これを coffeescript で使った時、いくらクリックしても、トグルしなかった。
原因に想像が付くだろうか?
$ ->
$('#button1').on 'click', ->
toggleState($(this).hasClass("active"))
理由は toggleState
が false
を返してくるからだった
イベントハンドラが false を返すと、イベントのバブリングが止まってしまう。
そして、bootstrap 自体は、document
でイベントを拾っているので、バブリングを止めてしまうと、toggle
まで届かず、処理が終わってしまう。
$(document)
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
Plugin.call($btn, 'toggle')
e.preventDefault()
})
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
})
よって、toggle
の処理として、click
を貼ることがあるなら、絶対に false を返してはいけない。
特に coffeescript は意図せずに、false を返しやすい。
上記の coffeescript は下記のように展開される
$(function() {
return $('#button1').on('click', function() {
return toggleState($(this).hasClass("active"));
});
});
coffeescript では、最後の行がreturn
されることは知っていても、普段あまり意識せずに書いていないだろうか。
coffeescript と bootstrap toggle button を 素の click で使うときは、充分気をつけよう。