flashメッセージを実装（非同期通信）

現在RubyとJavaScriptを用いて記事投稿サイトを作成しています。
今回はお気に入り登録/解除の際、**flashメッセージ**を表示できるようにしていきたいと思います。
お気に入り機能の実装は[こちら](https://qiita.com/ad1117wi/items/cffefa847caf3371fb68)

###■仕様等
・お気に入りアイコンをクリックするとページ上部にメッセージが表示される
・画面スクロールに追従する
・連続でアイコンを押下した際は最新のメッセージが割り込む
・jQueryを使用しない

###■完成後の動作とコード
[![Image from Gyazo](https://i.gyazo.com/3a294759ebd11a6fc8f7a3aaae93581b.gif)](https://gyazo.com/3a294759ebd11a6fc8f7a3aaae93581b)

```javascript:create.js.erb
//①お気に入りに登録した時の処理
if(document.getElementById('article_<%= @article.id %>').innerHTML = '<%= escape_javascript( render 'shared/articles', article: @article ) %>'){

//②flashメッセージが既に存在する場合は、それを削除する
  if(document.getElementById('flash-message')){
    document.getElementById('flash-message').remove();
  }

//③flashメッセージ(div要素)を生成する
  const flashMessage = document.createElement('div');
  flashMessage.setAttribute('class', 'flash-message')
  flashMessage.setAttribute('id', 'flash-message')
  flashMessage.setAttribute("style", `top: ${window.scrollY}px; animation-name: flash-message-fade;` );
  flashMessage.innerHTML = "お気に入りに登録しました"

//④flashメッセージの挿入先を取得(body)
  const body = document.querySelector("body");
  body.prepend(flashMessage)

//⑤flashメッセージの表示位置をページスクロールに合わせる
  document.addEventListener('scroll', function(){
    flashMessage.style.top = `${window.scrollY}px`
  })

//⑥flashメッセージを４秒後に消去する
  window.setTimeout(function(){
    flashMessage.remove();
  }, 4000);
}
```

###■お気に入り機能の実装
以前[こちら](https://qiita.com/ad1117wi/items/cffefa847caf3371fb68)で実装したものをそのまま使用しています。

###■flashメッセージの実装
####①お気に入り登録した時の処理
```javascript:create.js.erb
if(document.getElementById('article_<%= @article.id %>').innerHTML = '<%= escape_javascript( render 'shared/articles', article: @article ) %>'){
```
if分の条件として、お気に入り登録の処理を記述しています。

####②flashメッセージが既に存在する場合は、それを消去する
```javascript:create.js.erb
  if(document.getElementById('flash-message')){
    document.getElementById('flash-message').remove();
  }
```
flashメッセージ表示中に続けてお気に入りアイコン押下した際、
表示中のメッセージを消去して最新のメッセージを表示します。↓
[![Image from Gyazo](https://i.gyazo.com/c4a919f92f0f046c894684579edafc36.gif)](https://gyazo.com/c4a919f92f0f046c894684579edafc36)

####③flashメッセージ(div要素)を生成する
```javascript:create.js.erb
  const flashMessage = document.createElement('div');
  flashMessage.setAttribute('class', 'flash-message')
  flashMessage.setAttribute('id', 'flash-message')
  flashMessage.setAttribute("style", `top: ${window.scrollY}px; animation-name: flash-message-fade;` );
  flashMessage.innerHTML = "お気に入りに登録しました"
```
style属性の値に指定している`${window.scrollY}px;`は、現在のスクロール位置を返します。
この要素と`animation-name`で指定しているアニメーションのCSSは以下の通りです。↓

```css:index.css
@keyframes flash-message-fade {
  0% {
    display: inline;
    opacity: 0;
    transform: scaleY(-1);
    background-color: rgb(235, 247, 129);
  }
  10% { opacity: 0.5; }
  20% { opacity: 1; transform: scaleY(1) }
  90% { opacity: 1; transform: scaleY(1); }
  100% {
    opacity: 0;
    transform: scaleY(0);
    display: none;
    background-color: white;
  }
}

.flash-message {
  animation-duration: 3s;
  animation-fill-mode: forwards;
  opacity: 0;
  display: none;
  position: absolute;
  z-index: 2;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 70px;
  padding-top: 1%;
}
```

####④flashメッセージの挿入先を取得(body)
```javascript:create.js.erb
  const body = document.querySelector("body");
  body.prepend(flashMessage)
```
`body`を取得し、生成したflashメッセージのdiv要素を挿入します。

####⑤flashメッセージの表示位置をページスクロールに合わせる
```javascript:create.js.erb
  document.addEventListener('scroll', function(){
    flashMessage.style.top = `${window.scrollY}px`
  })
```
イベントに`scroll`を指定する事で、画面がスクロールされた際にイベント発火します。
flashメッセージのstyle属性のtopに先程の`window.scrollY`を代入します。
これによりメッセージがページスクロールに追従する様になります。↓
[![Image from Gyazo](https://i.gyazo.com/53233317fd8964aa035988d1eda6c4fd.gif)](https://gyazo.com/53233317fd8964aa035988d1eda6c4fd)

####⑥flashメッセージを４秒後に消去する
```javascript:create.js.erb  
  window.setTimeout(function(){
    flashMessage.remove();
  }, 4000);
}
```
`window.setTimeout`内に記述した処理は、指定時間後に実行されます。
flashメッセージを表示から４秒後に消去されるように設定しました。
create.js.erbの記述は以上です。

あとはdestroy.js.erb（お気に入り解除）に①の条件と③のメッセージ内容を変更したものを記述します。

以上で完成です。

###■参考文献
[https://developer.mozilla.org/ja/docs/Web/API/Window/scrollY](https://developer.mozilla.org/ja/docs/Web/API/Window/scrollY)