JQuery左右のslide

久しぶりにJQuery触りました。JQueryが優秀すぎて、自分がおバカになりそうだったのでしばらく触ってなかったのですが、とはいえ「楽に実装できるなぁ」って思いました。

正直<font color="red">**将来性は感じませんがw**</font>まだまだlegacyな会社(悪い意味じゃ無いよ)では、使われいるライブラリーですし、何よりも初心者が一番とっつきやすいツールでもあります。

## 本題

【使用画像】
![chick.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/b48fbae0-c523-f2f0-c1bd-698886a8715a.png)

【完成イメージ】
![camp_image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420031/75396b51-7d26-50c9-434a-d40716b530a2.gif)

やることは掲題のとおり、左右のSlideです。JQueryには`slideUp`,`slideDwon`はあるのですが、左右のSlideがなかったと思います。（違っていたらすいません。）

なので練習も含めてこの機能を実装してみました。是非参考にして下さい。

## html

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>slideX_JQuery</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- Google Font -->
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>
  <!-- Left Image -->
  <div class="left-img" id="leftImg"><img src="./img/chick.png"></div>
  <!-- Right Nav -->
  <nav>
    <div class="right-nav navToggle">MENU</div>
    <div class="nav-close navToggle">×CLOSE</div>
    <ul>
      <li><a href="#">manu1</a></li>
      <li><a href="#">manu2</a></li>
      <li><a href="#">manu3</a></li>
      <li><a href="#">manu4</a></li>
      <li><a href="#">manu5</a></li>
    </ul>
  </nav>
  <!-- JS -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <script src="./js/main.js"></script>
</body>
</html>
```

htmlはすごくシンプルです。念の為、`head`部分まで載せときますので、階層さえ整えてくれれば、最悪コピペでいけます。

## css

```css
@charset "UTF-8";
/* reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Noto Sans JP', sans-serif;
  line-height: 1;
}
ul{
  list-style: none;
}
a{
  text-decoration: none;
}
/* Left Image */
.left-img{
  transition: .3s;
  position: absolute;
  top: 50%;
  left: -60px;
}
.left-img.show{
  left: 0;
}
/* Right Navigation */
nav{
  height: 100%;
  /* 初期値は幅０ */
  width: 0;
  background: beige;
  border-left: 2px solid  #c9caca;
  /* 右上に常時配置させる */
  position: fixed;
  top: 0;
  right: 0;
  transition: .3s;
}
nav.show{
  /* showクラスが追加されると、幅200pxに上書きされる */
  width: 200px;
}
.right-nav{
  width: 30px;
  height: 100px;
  /* ボーダーは右側不要なので０を上書き */
  border: 2px solid #c9caca;
  border-right: 0;
  border-radius: 5px 0 0 50%;
  /* テキスト縦書き */
  writing-mode: vertical-rl;
  text-orientation: upright;
  text-align: center;
  vertical-align: middle;
  line-height: 30px;
  color: #e6b422;
  /* navの外側に相対配置。相対配置なので、navの挙動分は同時に動く。 */
  position: relative;
  top: 10px;
  left: -30px;
}
.nav-close{
  /* 初期値は非表示 */
  display: none;
  padding: 0 15px 0 1px;
  border-bottom: 1px solid black;
  /* bodyの右上に絶対配置 */
  position: absolute;
  top: 10px;
  right: 10px;
}
.nav-close.show{
  /* navが開閉されると、CLOSEボタンが表示される。 */
  display: block;
}
nav ul{
  /* liがnavの画面外でスタンバッているため、ul外の要素は非表示。 */
  overflow: hidden;
}
nav ul.show{
  /* liの枠外からのアニメーションを実行したいため、hiddenを通常のvisibleに上書き。 */
  overflow: visible;
}
nav li{
  background: #e6b422;
  border-top: 1px solid #c9caca;
  /* 枠外からスライドインするため、初期値では左側に相対配置。 */
  position: relative;
  top: 50px;
  right: 300px;
  transition: 1s;
}
nav li.show{
  background: #f5f5dc;
  /* navが開閉されたと同時に、相対配置のまま、位置指定を全て０に戻す。 */
  position: relative;
  top: 0;
  right: 0;
}
nav li:last-child{
  border-bottom: 1px solid #c9caca;
}
nav a{
  display: block;
  padding-left: 20px;
  line-height: 50px;
  color: #e6b422;
  transition: .3s;
}
nav a:hover{
  background: #e6b422;
  color: white;
}
```

これも`Reset`まで載せときます。難しそうなところはコメント書いてるんで見て下さい。

ポイントとしては`nav ul`の`overflow`の使い方でしょうか？
コメントにも書いていますが、`li`が時間差で左側からSlideするような機能を実装しているため、<font color="red">**ulの枠外にliが初期配置されています。**</font>

このままだと枠外に置いてある`li`が丸見えになってしまうので、`ul`の`overflow`で<font color="red">**枠外の要素を全て非表示にしています。**</font>

ただしすっと非表示だと今度は、`nav`メニュー開閉時のアニメーションが見えなくなってしまうため、<font color="red">**開閉時のみ`hidden`から初期値の`visible`に上書きしています。**</font>

それ以外は難しいことは無いかと思います。

## JQuery

```javascript
$(function(){
  // 変数宣言（let宣言でもOKだが今回は再代入不要なのでconstが望ましい）
  const leftImg = $('#leftImg');
  const navToggle = $('.navToggle');
  const liTags = $('nav').find('li');
  const showCls = 'show';
  // Left Image
  leftImg.on('click', function(){
    // クリックでshowクラスを追加。
    $(this).toggleClass(showCls);
  });
  // Right Navigation
  $.each(navToggle, function(i, btn){
    // 開閉ボタン2つに対して、繰り返し処理。
    $(btn).on('click', function(){
      // 先にnavを開閉。CLOSEボタン表示。ulのoverflow解除。
      $('nav').toggleClass(showCls);
      $('.nav-close').toggleClass(showCls);
      $('nav ul').toggleClass(showCls);
      // ulのoverflow解除後、liのアニメーション処理を実行。
      $.each(liTags, function(i, li){
        setTimeout(function(){
          $(li).toggleClass(showCls);
        },200 * i);
      });
    });
  });
})
```

ここも難しいことは無いです。
nav開閉時のアクションとして、先に`nav`,`nav-close`,`nav ul `にそれぞれ`showクラス`を追加し、<font color="red">**その後に`li`に対して処理を投げます。**</font>

`li`の処理は以下の様な流れになっています。
・`nav`内の`li`を取得。それを配列化。
・`$.each()`で配列のアイテム(`li`１つ１つ)に対し、`showクラス`を追加。
・`showクラス`の追加は、`setTimeout(func, n)`によって、nミリ秒ずつ処理を遅らせます。

ざっくりとこんなところです。

## 最後に
今回はJQueryで書きましたが、時間があったら通常のjavascriptの記述に変換したものを載せたいと思います。

やっぱり今後の需要としては他のモダンJSもやっていくべきなので、コードの変換は凄く勉強になります。

特にjavascriptをやると、<font color="red">**JQueryの裏側でどういった処理が流れてるのかを知れる**</font>ので、ロジカルに何で動いているのかが何となく分かります。

今回は簡単ですが、この辺で終わりにします。お疲れ様でした。









<font color="red">****</font>