JavaScriptメモ

# はじめに
メモ。
JavaScript、jQueryも。
HTMLも。
ブラウザはChrome。


# DOM 要素取り出し
childNodesとchildrenで動きがよめず戸惑ったので。
Laravelを使ってたのでbladeファイル。

```html:test.blade.php
<div id="test"> 
    あ
    <p>1</p>
    い
    <p>2</p>
    うえ
    <p>3</p>
    お
</div>

<script>
    // childNodesだと
    text = document.getElementById('test').childNodes;
    document.write(text[0].nodeValue);              // あ
    document.write(text[1].firstChild.nodeValue);   // 1
    document.write(text[2].nodeValue);              // い
    document.write(text[3].firstChild.nodeValue);   // 2
    document.write(text[4].nodeValue);              // うえ
    document.write(text[5].firstChild.nodeValue);   // 3
    document.write(text[6].nodeValue);              // お

    // childrenだと
    num = document.getElementById("test").children;
    document.write(num[0].firstChild.nodeValue);    // 1
    document.write(num[1].firstChild.nodeValue);    // 2
    document.write(num[2].firstChild.nodeValue);    // 3
</script>
```


childrenだとテキストノードは取得しない。

childNodesはテキストを入力してなくても改行が入る。

```html:test.blade.php
<div id="test2">
    <p>1</p>
    <p>2</p>
    <p>3</p>
</div>

<script>
    text2 = document.getElementById('test2').childNodes;
    document.write(text2[0].nodeValue);              //  (改行)
    document.write(text2[1].firstChild.nodeValue);   // 1
    document.write(text2[2].nodeValue);              // (改行)
    document.write(text2[3].firstChild.nodeValue);   // 2
    document.write(text2[4].nodeValue);              // (改行)
    document.write(text2[5].firstChild.nodeValue);   // 3
    document.write(text2[6].nodeValue);              // (改行)
</script>
```


改行しなければ改行が入らない。

```html:test.blade.php
<div id="test3"><p>1</p><p>2</p><p>3</p></div>

<script>
    text3 = document.getElementById('test3').childNodes;    
    document.write(text3[0].firstChild.nodeValue);  // 1
    document.write(text3[1].firstChild.nodeValue);  // 2
    document.write(text3[2].firstChild.nodeValue);  // 3
</script>
```



# HTMLを追加したりする

JavaScriptでは。

```javascript:scriptタグの中
// 生成
document.write("<p id='test'>あああ</p>");
// 変更
test.innerHTML = "いいい";
// 削除
test.innerHTML ="";
```
これらは使わなかった。


jQueryでは。

```javascript:scriptタグの中
// 生成
$("body").html("<p id='test1'>あああ1</p>");    // 上書き(body内を全て消して出力)
$("body").append("<p id='test2'>あああ2</p>");  // 後に追加(body内の一番下に出力)
$("body").prepend("<p id='test3'>あああ3</p>"); // 前に追加(body内の一番上に出力)
// 変更
$("#test1").html("いいい1");    // 上書き
$("#test2").text("いいい2");    // 上書き
// 削除
$("#test1").html("");   // 空白で上書き(実質削除)
$("#test2").remove();   // 要素ごと削除
$("body").empty();      // 要素を空に、$("body").html("")と同じ
```

append()とempty()を主に使ってた。
$()内の文字列はcssのセレクタと同じ指定方法。




# jQuery クラス操作

```javascript:scriptタグ内
$("body").append("<div id='test'></div>");
// クラス追加
$("#test").addClass("btn");     // btnというクラスを追加
// クラス削除
$("#test").removeClass("btn");  // btnというクラスを削除
// クラス確認
$("#test").hasClass("btn");     // btnクラスを持っていたらtrue、否false
// クラス取得
var cls = $("#test").attr("class");

```

クラスを変更したい場合は削除してから追加する。
クラス追加で適用されるstyleを変えてアニメーションとかできる。




# トグルボタン

ONOFFを切り替えられるボタンが欲しかった。
最初はCSSの方に迷い込んで大変だった。
最終的にはjQueryでクラスを変更し、ONOFFの見た目を切り替えた。

```html:game.blade.php
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<style>
    .button{
        outline: none;
        border: thin solid;
        width: 50px;
        height: 50px; 
        font-size: 40px;
        margin: 5px;
    }
    .off{
        background: lightgray;
        color: royalblue;
    }
    .on{
        background: royalblue;
        font-weight: bold;
        color: tomato;
    }
</style>

<script type="text/javascript">
    // ボタン配置
    $("body").append("<div id='btn4'></div>");
    $("#btn4").append("<button class='button off' onclick='clicked(this)'>1</button>");
    $("#btn4").append("<button class='button off' onclick='clicked(this)'>2</button>");
    $("#btn4").append("<button class='button off' onclick='clicked(this)'>4</button>");
    $("#btn4").append("<button class='button off' onclick='clicked(this)'>8</button>");

    // ボタンを押した時の処理
    const clicked = button => {
        if ($(button).hasClass('off')) {
            // クラス切り替え(見た目変わる)
            $(button).removeClass("off");
            $(button).addClass("on");
            // onになった時の処理

        } else {
            // クラス切り替え
            $(button).removeClass("on");
            $(button).addClass("off");
            // offになった時の処理

        }
    }
</script>
```

最初の`<script~`はjQuery使えるように。
`<style>~`はONOFFでボタンの見た目が切り替わるように。こんなに長々書かなくていい。
次の`<script~`ではまずボタンを4つ追加。普通にHTMLで書いてもいい。
`clicked関数` クラスを変更している。
引数で押されたボタンを受け取り、`$(button).hasClass('off')`でoffクラスを持っているか判断。
クラスがoffならonにし、onならoffにしている。

これでトグルボタンっぽいのができた。





# アニメーション

実例をば。

animate()関数を使ったカウントダウン。

```javascript:scriptタグ内
$("body").append("<div id='countdown'></div>");
// 3が0になるアニメーション
$({ count: 3 }).animate({ count: 0 }, {
    duration: 3000,
    easing: "linear",
    progress: function () {
        $("#countdown").text(Math.ceil(this.count));
    },
    complete: function () {
        $("#countdown").remove();
    }
});
```

まずアニメーションする要素を生成。
animate()を呼ぶ。(この呼び方をあまり理解していない)
`duration: 3000` 3000ms(3秒)かけてアニメーションする。
`easing: "linear"` イージングしない。(素直にアニメーションする)
`progress: function () { ~` アニメーションの1stepごとに行う処理。ここでは変化する数字を表示している。
`complete: function () { ~` アニメーション完了時に行う処理。要素を削除している。(消さないと0が残り続ける)

---

次にanimate()関数を使った出てきて消えるマル。

```html:game.blade.php
<style>
    #circle{
        width: 50px;
        height: 50px;
        border-radius: 50%;
        border: solid 3px orangered;
        opacity: 0;
    }
</style>

<script type="text/javascript">
    $("body").append("<div id='circle'></div>");
    // マル出て消えて出て消えるアニメーション
    $("#circle").animate({ opacity: "1" }, 2000)
    .animate({ opacity: "0" }, 2000)
    .animate({ opacity: "1" }, 0)
    .delay(1000).animate({ opacity: "0" }, 0);
 </script>
```

`<style>`タグ内はマルにしてるだけ。
animation().animation()のようにピリオドで繋ぐとアニメーションが終わったら次のアニメーションに進むようにできる。
`$("#circle").animate({ opacity: "1" }, 2000)`で2000msかけてopacity(不透明度)を1にしている。フワーっと出てくる。
`次の行`で2000msかけてまたopacityを0にしている。フワーっと消える。
`その次の行`で0msかけてopacityを1に。パッと出てくる。
`最後の行`で1000ms待った後、0msかけてopacityを1に。パッと消える。

---

最後にanimate()を使わない、cssとjQueryなアニメーション。

```html:game.blade.php
<style>
    #bar{
        background: gold;
        width: 0px;
        height: 30px;
        transition: 5s linear;
    }
    #bar.active{
        background: royalblue;
        width: 200px;
    }
</style>

<script type="text/javascript">
    $("body").append("<div id='bar'></div>");
    $("body").append("<button onclick='barAnim(this)'>のびる</button>");

    const barAnim = button => {
        if (!$("#bar").hasClass("active")) {
            $("#bar").addClass("active");
            $(button).text("ちぢむ");
        } else {
            $("#bar").removeClass("active");
            $(button).text("のびる");
        }
    }
</script>
```

`<style>`内、`#bar`の中。
`transition: 5s linear` これでスタイルが切り替わる時5sかけて一定に変化する。これを指定しないとパッと切り替わる。
ボタンを用意して押すたびに切り替わるようにする。
`active`クラスが付与されると`#bar.active`のスタイルに切り替わり、
`background`がgoldからroyalblueに、`width`が0pxから200pxに、5sかけて切り替わる。




# jQuery css操作

jQueryでcssを操作する。

```javascript:scriptタグ内
$("body").append("<p>こんちあ</p>");
// css生成・変更
$("p").css("color", "salmon");
$("p").css({"color": "steelblue", "font-weight": "bold"});
// css削除
$("p").css({"color": "", "font-weight": ""});
// css取得
var color = $("p").css("color");
```

生成も変更も削除も同じ書き方。生成する時まだないプロパティなら生成、既にあるなら変更(上書き)、空白文字で上書きしたら削除。
プロパティを1つだけ生成する場合と複数生成する場合で書き方が変わる。