ナンを咲かせる木を作った
題して「枯れ木にナンを咲かせましょう」
See the Pen 枯れ木にナンを咲かせましょう by Thugumi Ishimaru (@thugumi-ishimaru) on CodePen.
「ナンを咲かせる」ボタンを押したら木にナンが生るクソアプリを作りました。
20個までナンを咲かせることができます。
遊び方
-
- 「ナンを咲かせる」ボタンを押す
-
- ナンが咲く
以上!!!!!!!!!!!!とっても簡単です!!!!!!!!!!!誰でも遊べる!!!!!!!!!!
そしてクソアプリ!!!!!もちろんなんの役にも立たない!!!!!!!
アプリもクソなのですが、ソースもクソなので何がクソなのかをこちらに解説していこうと思います。
このアプリを反面教師にしていただけたらと思います。
クソアプリのここがクソ
クソ部分その1:何の得もない
この木にナンができたからといって、「......で?」で終わると思うんです。
そう、本当にナンの役にも立ちません。
クソアプリなんだからいいですよね。。。クソなんだから。。。
クソ部分その2:scssが長すぎる
ソースをみてみましょう。
<div class="nan"></div>
.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
に変更
<ul class="nan"></ul>
$('.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文が使えるので、そちらを使用します。
.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
.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;
}
}
}
}
これで全てのナンをバラバラの位置に表示することができます。
このリファクタを行ったナンの木がこちら
See the Pen 枯れ木にナンを咲かせましょう(リファクタバージョン) by Thugumi Ishimaru (@thugumi-ishimaru) on CodePen.
この実装のメリット
- scssのみで実装可能
- scssのソースがスッキリして読みやすくなる
この実装のデメリット
- 数値は
random()
なので毎回うまく配置されるとは限らない。前提が「この位置に絶対配置するのである」の要件にはそぐわない。
まとめ
クソアプリと共にクソースコードを紹介しました!
クソコードを修正するのに、以下を明確にしています。
-
枯れ木にナンを咲かせるクソアプリを作った
-
何がクソか
- 要素が増えたときに死ぬ
- 長い
- 読みづらい
-
scssで以下を修正してクソから少し脱却する
- ルールを明確にする
- for文を使用する
- random()を使用する
枯れ木にナンを咲かせましょう!!!!!!!
おまけ
.nan
って命名にしてますが、JavaScriptではNaN
という予約語が存在するので、
こんがらがらないように気をつけましょう。
れむさんありとうございます!
https://www.javadrive.jp/javascript/ini/index5.html