ナンの実りもないクソアプリを作った

## ナンを咲かせる木を作った

題して「枯れ木にナンを咲かせましょう」

<p class="codepen" data-height="589" data-theme-id="dark" data-default-tab="css,result" data-user="thugumi-ishimaru" data-slug-hash="RwNpyKz" style="height: 589px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="枯れ木にナンを咲かせましょう">
  <span>See the Pen <a href="https://codepen.io/thugumi-ishimaru/pen/RwNpyKz">
  枯れ木にナンを咲かせましょう</a> by Thugumi Ishimaru (<a href="https://codepen.io/thugumi-ishimaru">@thugumi-ishimaru</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

「ナンを咲かせる」ボタンを押したら木にナンが生るクソアプリを作りました。
20個までナンを咲かせることができます。

## 遊び方

* 1. 「ナンを咲かせる」ボタンを押す
* 2. ナンが咲く

以上！！！！！！！！！！！！とっても簡単です！！！！！！！！！！！誰でも遊べる！！！！！！！！！！
そしてクソアプリ！！！！！もちろんなんの役にも立たない！！！！！！！

アプリもクソなのですが、ソースもクソなので何がクソなのかをこちらに解説していこうと思います。
このアプリを反面教師にしていただけたらと思います。

## クソアプリのここがクソ

### クソ部分その1：何の得もない
この木にナンができたからといって、「......で？」で終わると思うんです。
そう、本当にナンの役にも立ちません。

クソアプリなんだからいいですよね。。。クソなんだから。。。

### クソ部分その2:scssが長すぎる
ソースをみてみましょう。

```index.html
<div class="nan"></div>
```

```style.scss
.nan {
  width: 400px;
  height: 300px;
  position: absolute;
  top: -100px;
  &_item {
    position: absolute;
    z-index: 1;
    &:nth-child(1) {
      left: 0;
      top: 0;
    }
    &:nth-child(2) {
      left: 100px;
      top: 0;
    }
    &:nth-child(3) {
      left: 200px;
      top: 0;
    }
    &:nth-child(4) {
      left: 300px;
      top: 0;
    }
    &:nth-child(5) {
      left: 0;
      top: 100px;
    }
    &:nth-child(6) {
      left: 100px;
      top: 100px;
    }
    &:nth-child(7) {
      left: 200px;
      top: 100px;
    }
（中略）
    &:nth-child(20) {
      left: 200px;
      top: 100px;
    }
```

**scssファイル読みづら！！！！！！！！**
**20個以上増やしたくなった時にまたscssに増やさんといけんとか頭痛くない？！**
**しかもいちいちズラすの？！？！？！？！？？！**
**間に`.nan_item`じゃないもの入ってきたら死ぬよ？！？！？！？？！**

と、色々出てくるんです。
じゃあどうすればいいか、、、今回はscssのみで解決できる方法をお伝えしようかと思います。

#### 解決方法手順その1： ルールを明確にする

> 間に`.nan_item`じゃないもの入ってきたら死ぬよ？！？！？！？？！

なぜ死ぬか、`nth-child(n)`を使っているからです。
と思うのですが、その前にルールを明確にしていないのですね。
ではルールを明確にしてあげましょう。

ということで「`.nan`以下には`.nan_item`しか入れちゃ嫌！！！」と**ルール化**しちゃいましょう。コードで語るのです。
`<ul>`タグの配下には`<li>`のみ記述が許可されているのでそのルールを利用します。

* `div.nan`を`ul.nan`に変更
* `div.nan_item`を`li.nan`に変更

```index.html
<ul class="nan"></ul>
```

```script.js
$('.nan').append('<li class="nan_item"><img src="https://illust-shokudo.com/assets/item/other_00001.png" alt=""</li>');
```

これで、`.nan`と`.nan_item`の間に部外者を入れられなくなりました。

#### 解決方法手順その2： for文で`nth-child(n)`を生成
> **20個以上増やしたくなった時にまたscssに増やさんといけんとか頭痛くない？！**

大変面倒ですよね。次にこれを解決しましょう。
scssではfor文が使えるので、そちらを使用します。


```style.scss
.nan {
  width: 400px;
  height: 300px;
  position: absolute;
  top: -100px;
  &_item {
    position: absolute;
    z-index: 1;
    @for $i from 1 through 20 {
      &:nth-child(#{$i}) {
       top: 0;
       left: 0;
      }
    }
  }
}
```

これで`nth-child`地獄は脱出しました。
しかし、このままでは配置位置が全て同じになってしまう。。。じゃあどうしよう。。。

次の手順をみていきましょう。

#### 解決方法手順その3： 絶対配置の配置位置をランダムにする

> このままでは配置位置が全て同じになってしまう。。。

以下の記事にもあるようにscssでは`random()`が使用できます。
これによって、ランダムの数値を当てることができるようになります。
今回はナンの位置を数値で指定していますよね。こちらを使ってみましょう。
https://qiita.com/tonkotsuboy_com/items/909b4073459ecaf7a435

```style.scss
.nan {
  width: 400px;
  height: 300px;
  position: absolute;
  top: -100px;
  &_item {
    position: absolute;
    z-index: 1;
    @for $i from 1 through 20 {
      &:nth-child(#{$i}) {
        left: random(300) + px;
        top: random(300) + px;
      }
    }
  }
}
```

これで全てのナンをバラバラの位置に表示することができます。

このリファクタを行ったナンの木がこちら

<p class="codepen" data-height="581" data-theme-id="dark" data-default-tab="css,result" data-user="thugumi-ishimaru" data-slug-hash="jOEmaRE" style="height: 581px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="枯れ木にナンを咲かせましょう（リファクタバージョン）">
  <span>See the Pen <a href="https://codepen.io/thugumi-ishimaru/pen/jOEmaRE">
  枯れ木にナンを咲かせましょう（リファクタバージョン）</a> by Thugumi Ishimaru (<a href="https://codepen.io/thugumi-ishimaru">@thugumi-ishimaru</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#### この実装のメリット
* scssのみで実装可能
* scssのソースがスッキリして読みやすくなる

#### この実装のデメリット
* 数値は`random()`なので毎回うまく配置されるとは限らない。前提が「この位置に絶対配置するのである」の要件にはそぐわない。

## まとめ
クソアプリと共にクソースコードを紹介しました！
クソコードを修正するのに、以下を明確にしています。

* 枯れ木にナンを咲かせるクソアプリを作った

* 何がクソか
    * 要素が増えたときに死ぬ
    * 長い
    * 読みづらい
* scssで以下を修正してクソから少し脱却する
    * ルールを明確にする
    * for文を使用する
    * random()を使用する

枯れ木にナンを咲かせましょう！！！！！！！


## おまけ
`.nan`って命名にしてますが、JavaScriptでは`NaN`という予約語が存在するので、
こんがらがらないように気をつけましょう。
[れむ](https://twitter.com/www_REM_zzz)さんありとうございます！
https://www.javadrive.jp/javascript/ini/index5.html