概要
Railsにてエラー等が発生した時、フラッシュを使用し、ページ上部にメッセージを表示させ方法はよく行うことだと思います。
基本的にページを再読み込みするか、別のページへ移動するかしない限り、フラッシュは上部に表示されたままです。
この表示をページを変えなくてもフェードアウトするようプログラムする。
方向性
基本的なflashの設定を行いviewに配置する。class属性を指定し、javascriptでタイマー設定をし、新たなclassを追加し、cssを読み込ませます。
ちなみにjQueryにfadeout()というメソッドがあり、そちらを使うこともできる(記述も簡単である)。
しかし、フェードアウトした後、表示されていたflashの範囲分、ページが上部に急激に上がるため、ユーザー側の立場を考えると困ると考えました。(例:クリックしようとした瞬間、または記事を読んでいる時ページが急激に動く等。)
勉強の意味も込めて、違った方法でフェードアウトさせてみました。
事前準備
controllerでのflashの設定、javascriptの設定等は行われている前提とします。
1.該当項目にclass属性を設定
<body>
<% if flash.notice %>
<p class="fadeoutTarget"><%= flash.notice %></p>
<% end %>
</body>
flash.noticeを囲うpタグにclass属性で"fadeoutTarget"と設定します。もちろん名前は任意で設定可能です。
2.javascriptの設定
$(document).on(turbolinks:load, function() {
/* fadeoutTargetというclassを持った要素を選択 */
const fadeoutElement = document.querySelector(".fadeoutTarget");
/* 一定時間経過したらfadeoutというclassを追加する */
function flashFadeout() {
setTimeout(function() {
fadeoutElement.classList.add("fadeout");
}, 5000);
}
/* fadeoutTargetという要素を持ったdocumentがあれば実行 */
if (fadeoutElement != null) {
window.onload = flashFadeout();
}
.querySelector()で任意のclass属性を持った要素を選択します。
この場合、pタグ内のflashの要素を取り出すように設定しています。
setTimeout()で一定時間後、関数を実行するというプログラムになります。
数字の箇所は任意で設定できます。
最後のif文はなくても動くのですが、処理上はfadeoutElementがない時(flash:noticeがない時)、"fadeoutElementがないですよ!"というエラーが出てしまうため、このようにif文で囲っております。
3.cssの設定
p.fadeoutTarget.fadeout {
opacity: 0;
transition: 1s;
}
前項のjavascriptが機能した時、cssが適用されフェードアウトされます。
厳密にはその場で透明になるため、フェードアウト後ページが急激に動いたりすることはありません。
まとめ
要素をフェードアウトさせる方法はたくさんありますので、その都度必要な方法で処理していけるようにしていきたいです。
今回の場合、ページの急激なスクロール移動はありませんが、上部にflash分の余白ができてしまうため、少し見栄えが悪いかもしれません。
個人的には、納得した形で収まったと考えております。またjavascriptの勉強にもなり良い機会でした。