JavaScript 備忘録

## 書く場所（HTML内に記述する場合）
特に理由が無い場合はbodyタグ内の一番下に記述する。
（理由）JavaScriptはHTMLが読み込まれてから実行されるため。

## 外部ファイルで読み込む場合
* Thymeleafでは、特定のディレクトリとは「src/main/resources/static/」のことを指す。
* 特定ディレクトリ直下に「js」フォルダを作成し、「sample.html」から「test.js」を読み込む例

```sample.html
<head>
<script th:src="@{/js/test.js}"></script>
</head>
<body>
<div id=result></div>
<script th:src="@{/js/get_time.js}"></script>
</body>
```
```src/main/resources/static/js/test.js
console.log("テスト");
alert("テスト");
```

*  特定ディレクトリ直下に「js」フォルダを作成し、「sample.html」から「get_time.js」を読み込む例

```get_time.js
//HTML側の呼び出し場所に注意。
//→ id:resultよりも上で呼び出すと、innerHTMLがエラーになる

//id_resultを取得
var ele = document.getElementById("result")

var dayOfWeek = new Array("日","月","火","水","木","金","土");
var myDate = new Date();
var theDate = myDate.getDate();
    console.log("theDate:"+theDate);
var theDay = dayOfWeek[myDate.getDay()];
    console.log("theDay"+theDay);
var theFullYear = myDate.getFullYear();
    console.log("theFullYear"+theFullYear);
var theMonth = myDate.getMonth()+1;
    console.log("theMonth"+theMonth);

    console.log(theFullYear + "年" + theMonth　+ "月" + theDate + "日(" + theDay + ")");
    ele.innerHTML = theFullYear + "年" + theMonth　+ "月" + theDate + "日(" + theDay + ")";
```

## コンソールログ

```html
<script>
 console.log("テスト");
 console.log(1000);
</script>
```
### 確認方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/5ea216cc-af33-98c6-1f67-dd19e0547c62.png)

## ダイアログ出力
```html
<script>
 alert(10);
</script>
```
## 確認ダイアログ
```html
<script>
 window.confirm('本当に追加してよろしいですか？');
</script>
```
## ボタン押下 + 条件分岐
```html
--------------------------------------------------------------------------------------
<button type='submit' name='action' value='add' onclick="buttonClick()">追加</button>
<input type="submit" value="追加" onclick="buttonClick()/>
--------------------------------------------------------------------------------------
<script>
  function buttonClick(){
  var result = window.confirm('追加したカテゴリーは削除できません。本当に追加してよろしいですか？');
    if( result ) {
       console.log('OKがクリックされました');
       return true;
     } 
     else {
       console.log('キャンセルがクリックされました');
       return false;
     }
   }
</script>  
```
## submitイベントをキャンセル
```html
--------------------------------------------------------------------------------------
<form method="post" onsubmit="return cancelsubmit()" th:action="@{/housework}">
  <input type="text" th:field="*{categoryName}"/>
  <button type='submit' name='action' value='add'>追加</button>
  <!-- input type="submit" value="追加"/-->
</form>
--------------------------------------------------------------------------------------
<script>
  function cancelsubmit(){
  var result = window.confirm('追加したカテゴリーは削除できません。本当に追加してよろしいですか？');
    if( result ) {
       console.log('OKがクリックされました');
       return true;
     } 
     else {
       console.log('キャンセルがクリックされました');
       return false;
     }
   }
</script>  
```
### ポイント
|ポイント|説明|備考|
|----|----|----|
|onsubmit="return cancelsubmit()"|formタグ内に記述|resultがfalseの場合、submitイベントをキャンセルする。|
https://techacademy.jp/magazine/44924

## オンクリックイベント
```onclick .js
    document.getElementById("submit-edit5").onclick = function() {
        var targetDateTag = document.getElementById("target_date");
        var tDate = targetDateTag.innerHTML;
        makeSendData(tDate,"submit-edit5")
    };
```


## getElementById
### input type=textに値を入れる例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/1967479d-51b7-cf8e-262c-b80f33154efd.png)

```javascript
   <span id="id_text_houseworkName">浴室清掃</span><br>     
   <input type="text" id="id_input_houseworkName" name="houseworkName" value=""/>
```
```javascript
   <!-- Thymeleafで記述した例 -->
   <span id="id_text_houseworkName" th:text="${hWkList.houseworkName}"></span><br>     
   <input id="id_input_houseworkName" type="text" name="houseworkName" th:value="*{houseworkName}" th:field="*{houseworkName}"/>
```
```javascript
   <script>
     const HOUSEWORK_NAME =document.getElementById("id_text_houseworkName").innerHTML;
     document.forms.id_form1.id_input_houseworkName.value = HOUSEWORK_NAME;
   </script>
```
### うまくいかない時
|不具合内容|確認事項|備考|
|----|----|----|
|Cannot read property ‘プロパティ名’ of undefined|指定しているid名を記述ミスしていないか||
|Cannot read property 'value' of null|document.getElementById("id_text_houseworkName").value;としていないか|例のようにタグとタグの間の文字列を取得したい場合は「innerHTML」を使用する。|

## getElementsByClassName
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/e1c15e80-a3ff-8811-2bb7-7999b765dfc3.png)

```html
<!--中略-->
    <input class='gram_slider' type="range" name="use_gram">
    <span class="msg">g</span>
<!--中略-->
    <input class='gram_slider' type="range" name="use_gram">
    <span class="msg">g</span>
<!--中略-->
    <input class='gram_slider' type="range" name="use_gram">
    <span class="msg">g</span>
```
```javascript
document.addEventListener('DOMContentLoaded',function(){
  //宣言・・・【A】
  var targets = document.getElementsByClassName("gram_slider");
  var msg = document.getElementsByClassName("msg");
  
  //すべてのtargetsに対してsetAttributeとaddEventListenerを付与する・・・【B】
  for(var i = 0; i < targets.length; i++){
    targets[i].addEventListener('input', inputChange);
    msg[i].innerText =  targets[i].value + 'g';
  }
  
  //上記処理【B】でinputChangeが付与されたtargetsの値が変化する度に呼び出される・・・【C】
  function inputChange(event){
    for(var i = 0; i < targets.length; i++){
     msg[i].innerText =  targets[i].value + 'g';
    }
  }
},false);
```
|ポイント|説明|備考|
|----|----|----|
|【A】|クラス名を配列に代入する|初め一回だけ呼ばれる|
|【B】|配列内の要素全てにイベントリスナーを付与する(addEventListener)|初め一回だけ呼ばれる|
|【C】|イベントリスナーを付与されたすべての要素に発火処理|値が変わる度に呼ばれる|

### selectの値を変更する例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/3e77594c-c433-fa4d-65c6-75e41a633c1a.png)

```javascript
<span id="id_category_name" th:text="${hWkList.categoryName}"></span><br>

<select id="id_select_category_name" th:field="*{categoryName}">
     <option th:each="houseworkList:${categoryList}"  th:object="${houseworkList}" th:text="*{categoryName}" th:value="*{categoryName}">
</select>
```
    
```javascript

 const CATEGORY_NAME = document.getElementById("id_category_name").innerHTML;    
 document.getElementById("id_select_category_name").value=CATEGORY_NAME;
```
|ポイント|説明|備考|
|----|----|----|
|document.getElementById("id_select_category_name").value|valueで値を指定できる。||


## forEach
```:サンプル
const array = [10, 20, 30, 40, 50];

array.forEach((value, index, array) => {
  console.log(`${value}は、[${array}]の中で ${index} 番目の要素です`);
});
```

|基本構文|ポイント|
|----|----|
|arr.forEach((value, index, array) => {<br> 実行したい処理<br>});|基本構文でアロー演算子が入っているので、無名関数の話とごっちゃにしないこと||

https://tcd-theme.com/2021/07/javascript-foreach.html?gclid=EAIaIQobChMIkq6VyriZ9QIViauWCh1KjQ-iEAAYASAAEgI4i_D_BwE

## 無名関数

https://qiita.com/may88seiji/items/4a49c7c78b55d75d693b

```js
//基本
let getTriangle = function(base,height){
 return base * height / 2;
};
console.log('三角形の面積は' + getTriangle(10,2));//三角形の面積は10


//アロー演算子有り
let getTriangle = (base, height) => {
  return base * height / 2;
};
console.log('三角形の面積は' + getTriangle(10,2));//三角形の面積は10
```

|基本構文|
|----|
|(引数,...)=>{...関数の本体...}|

## Listのフィールドにアクセス
```
    const list =/*[[${cookHisList}]]*/
	console.log(list[0]);
    console.log(list[0].menuName);
```

## createElement
```
<body>
<div id="create-test"></div>
</body>
-----------------------------------------------------
    var div1 = document.getElementById("create-test");
    testStr="秋の田の<br>仮庵の庵の<br>苫をあらみ<br>わが衣手は<br>露にぬれつつ";
    div2 = document.createElement( "div" );
    div2.innerHTML = testStr;
    div1.appendChild(div2);

------------------------------------------------------
実行結果↓↓
秋の田の
仮庵の庵の
苫をあらみ
わが衣手は
露にぬれつつ
```

### うまくいかない時
|項目|説明|備考|
|----|----|----|
|createElementした要素が表示されない|appendChildしていない|あらかじめタグを用意しておき、そこへappendChildでくっつけないといけない|

## リンクをクリックしてJavaScript発動
```
<a href="javascript:OnLinkClick();">Exec</a><br />

<script>
function OnLinkClick() {
  console.log("test");
}
</script>
```
|項目|説明|備考|
|----|----|----|
|OnLinkClick()|呼び出す関数名|任意の関数を設定する|


## 日付の落とし穴

```
sampleDate = 2022/3/14
test(sampleDate)
function test(date){
console.log(date)
}
【理想】
2022/3/14
【実行結果】
48.142857142857146

innerHTML等で使用する際はエスケープの打ち方に注意すること。
cell.innerHTML = "<a href=\"javascript:SendData(\'" + sampleDate + "\');\">"

```
## 連想配列(Dictionary)

```
var color =getColor();
alert(color['A1']);
alert(color['A2']);
alert(color['A3']);

function getColor(){
    return {
        A1: "赤",
        A2: "青",
        A3: "黄色",
    };
}
```
複数の型も格納可能
var user = { name:'太郎', age:32, tel:'080-1234-5678' };
https://www.sejuku.net/blog/27965