はじめに
Rails app内で、カルーセルスライダーやsubmitの自動送信といったjQueryで実装した機能が正常に動作しない現象に何度か遭遇しました。
本記事ではその対処法を紹介します。
注意
Rails学習中の初学者が備忘録を兼ねて書いています。
内容に誤りを含む可能性・さらに良い手法がある可能性が多分にありますので、参考にする際はその点ご留意ください。
RubyとRailsのバージョン
下記のバージョンにて動作確認しています。
- Ruby 2.5.1
- Rails 5.2.1
現象と原因、解決策
僕が遭遇したエラーは下記の2点でした。
- 初回読み込み時にjQuery(スライダー)が動かない。リロードしたら動き出す。 →(原因)Turbolinksが発動し、ページ読み込みを起点としたjQueryが発火しない
- AjaxでHTMLの一部を差し替えた後、差し替え部に埋め込んだjQuery(submit送信)が動かない。 →(原因)Ajaxで差し替えられた部分ではページ読み込みを起点とするjQueryが発火しない
(解決策)
どちらの問題も、イベントの発火タイミングを設定し直すことで修正できました。
修正前のコード
custom.js
に下記の記載をしていました。
// carousel-slider(bxslider)
jQuery(document).ready(function() {
$('.bxslider').bxSlider({
});
});
// submit自動送信
jQuery(document).ready(function() {
$('.select-box').change(function() {
$(this).parent().submit();
});
});
上記の jQuery(document).ready
や、 $(function()
の記述では、ページの読み込みを起点として発火します。
つまり、画面の一部が切り替わった場合はイベントが発生しないことになります。
そこで、Turbolinksを無効化させる、Ajax後にも発火するように設定する、ということで対処していきます。
Turbolinksについては こちらの記事 で詳しく解説されています。
修正後のコード
修正後のコードがこちらです。
// carousel-slider(bxslider)
jQuery(document).on('turbolinks:load', function(){
$('.bxslider').bxSlider({
});
});
// submit自動送信
jQuery(document).bind('ready ajaxComplete', function() {
$('.select-drop').change(function() {
$(this).parent().submit();
});
});
-
turbolinks: load’
とすることで、初回読み込み時、リロードどちらでも発火するようになります。 -
ajaxComplete
とすることでAjaxが完了したのちに発火するように設定できます。今回はbind(‘ready ajaxComplete’)
とすることで初回読み込み時、Ajax後の両方で動作するようにしています。
完成
綺麗な解決法ではないかもしれませんが、なんとか無事に狙い通りの機能を実装できました。
jQueryについてはもっと勉強が必要そうです。。。
参考
- https://ryoutaku-jo.hatenablog.com/entry/2019/01/15/213420
- Rails5でjqueryを動かす方法 - Qiita
- jQueryでajax完了後に実行開始したい処理があるときの対応 - ホームページ制作 株式会社KOP
- jQuery: both .ready() and .ajaxComplete - Stack Overflow
#Qiita