Web制作で使えるJavaScript集

#初めに
この記事ではJavaScriptの技術からWeb制作に使える便利な機能を３つ紹介します。
## 1 Ajax
まず一つ目はAjaxです。
この機能はWebサイト上にマップなどの外部のサイトから情報を取得するためにサーバー側と非同期通信を行う技術です。
この機能を使うにはXMLHttpRequest()というJavaScriptから提供されているAPIを使います。
初めにインスタンスを作成します。以下例↓

```javascript
var xhr = new XMLHttpRequest();
```
その次にインスタンス xhrを使って、サーバー名、取得方法、データを取得する方法を決めます。
xhr.open() は通信する方法 GET、POST やサーバーの場所URL等を指定し、xhr.send()を入力で通信を開始します。

xhr.onreadystatechangeでサーバーから取得したデータを受け取る。ここで「通信成功か？」「通信完了か？」等をif文で条件分岐しながら確認する必要します。以下例↓

```javascript
xhr.open(取得方法, サーバーの場所);
xhr.send();
xhr.onreadystatechange = function() {
    if(いつデータを取得するか) {
        //データを取得後の処理を入力
    }
}
```
##readyStateで条件分岐のやり方
サーバーからのデータを受け取るのにonreadystatechangeを利用しました。
しかし、そもそも通信が完了して成功しているのか調べないと目的のデータを取得できているか分かりません。
readyStateを使えば分かりますので、これを使って条件分岐の処理を入力していきます。
ここでは値が０〜５まであります。
０は通信が実行されていない状態 1は通信準備が完了してた状態 2はサーバーと通信が開始されている状態
３はサーバーからデータを取得している状態 4サーバーからデータを取得して通信が終了した状態
今回は4の全ての処理が終わった状態で確認します。readyStateの値が4であれば、サーバーからデータを取得する処理を行います。
以下例↓

```javascript
xhr.onreadystatechange = function() {
    if ( xhr.readyState === 4 ) {
        //データを取得して処理するコードを書く
    }
}
```
##GETで通信
Ajax通信では、GET,POSTによる方法でプログラムを書ます。以下例↓

```javascript
var xhr = new XMLHttpRequest();
xhr.open('GET', URL);
xhr.send();
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {
        //データを取得後の処理を書く
    }
}
```
インスタンス作成で「open() / send()」で通信を開始。
次はサーバーからのデータ取得方法です。
サーバーの場所のURLをopen()の引数にする。サーバーにある「test.json」というファイルを選択。

```javascript
xhr.open('GET', 'http://test.com/test.json');
```
この情報を取得するためにはresponsetTextを使います。

```javascript
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 100) {
        console.log( xhr.responseText );
    }
}
```
これでGETでの通信は終了です。
##POSTで通信
POSTも同じようにXMLHttpRequestのインスタンス作成、open sendで通信を開始。openの引数は、POSTを指定し、指定ののURLを書きます。
次は、setRequestHeader()を使ってcontent-typeを指定します。これがないとデータを正しく受信できない場合があります。
次にsendの引数、GETでURLに含めていた情報をここに書く。

```javascript
var xhr = new XMLHttpRequest();
 
xhr.open('POST', 'http://test.com');
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
xhr.send( 'q=hogehoge' );
```
##エラー確認
最後にエラーを確認します。エラーが発生した場合にメッセージを取得する方法です。

```javascript
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        //データ取得の処理
    }
};
```
statusの値が200の場合は正常で、それ以外のエラーコードは[HTTPステータスコード](https://digitalidentity.co.jp/blog/seo/seo-tech/howto-http-status-code.html)で確認してください。
##2 リストの並び替えや検索機能を付けられるList.js
これはWebページ内のリストの並び替え、検索機能を付けれるものです。
まず初めにライブラリを使用するので次のページからダウンロードして下さい。[List.js](https://listjs.com/overview/download/)
Download uncompressed List.jsを押してダウンロードです。
以下の例のように何らかのリストを作ります。

```html
<div id="first-list">
  <input class="search" placeholder="Search" />
  <button class="list" data-sort="test">
  </button>
  <ul class="list">
    <li>
      <h3 class="test">テスト</h3>
      <p class="namber">1</p>
    </li>
    <li>
      <h3 class="test">テスト２</h3>
      <p class="namber">2</p>
    </li>
    <li>
      <h3 class="test">テスト３</h3>
      <p class="namber">3</p>
    </li>
    <li>
      <h3 class="test">テスト４</h3>
      <p class="namber">４</p>
    </li>
    <li>
      <h3 class="test">テスト5</h3>
      <p class="namber">5</p>
    </li>
  </ul>
</div>

<script src="list.js"></script>

<script>
    var options = {
    valueNames: [ 'test', 'namber' ]
    };
    
    var userList = new List('first-list', options);
</script>
```
ボタンを押して名前があいうえお順、番号順に並び替えられます。検索蘭に名前、年齢のを入力すると存在する項目のみが残ります。
##設定方法
初めにul,li要素と並び替えボタン、検索窓をdivで囲みます。そのdiv要素にIDを設定します。
次はul要素にclass="list"を設定します。このクラスはlistにしてください。それ以外は対応していません。
最後は、並び替えや検索対象の要素に同じクラスを指定します。
scriptのlist.jsはそのまま書いてください。
並び替えや検索は一つだけじゃなく、'test','namber'と二つ以上付け加えることが出来ます。
optionは変更可能で、valueNamesは変更不可です。
userListは自由に指定して、first-listは指定したdiv要素と同じにします。
検索機能はul要素より前に記述を書きます。クラスはclass="search"にします。
並び替え機能は、ul要素にボタンを設置するだけです。クラスはclass="sort"にします。
また、どの要素で並び替えするか指定します。この例だとdata-sort="test"としているので、testの順に並び替えれます。
これでだいたいの事が出来ます。
##3 タブ切替メニュー
最後はどのサイトでもほとんどあるタブを切替て情報を分別する機能です。
##HTMLマークアップ
まず初めにHTMLでマークアップしていきます。
HTMLでは、タブとタブを切り替えて表示するコンテンツ要素を、3つ作成しました。
デフォルトでは、現在のタブがclassにtabactionをもつ「Tab-1」となり、コンテンツの要素は「Content-1」を表示しています。
「Content-1」の要素は、classをshow CSSでdisplay:block; にして表示、その他のコンテンツの要素は、display:none; を指定して非表示とします。

```html
<div class="tab-meny">
	<!--それぞれのタブ-->
	<ul class="tab-contents">
		<li class="tab tab-1 tabaction">Tab-1</li>
		<li class="tab tab-2">Tab-２</li>
		<li class="tab tab-3">Tab-3</li>
	</ul>
		<!--タブ切り替で表示するコンテンツ-->
    <div class="meny-contents">
		<div class="meny tab-1 show">Content-1</div>
		<div class="meny tab-2">Content-2</div>
		<div class="meny tab-3">Content-3</div>
	</div>
</div>
```

##JavaScriptのマークアップ
JavaScriptは、タブをクリックすると、タブ、コンテンツのclassの値を変更します。それでタブをクリックして切り替えた時に、コンテンツの内容を変更する仕組みです。

コード2行目は、すべてのタブ classにtabの値の要素に対して、addEventListenerメソッドでクリックイベントを適用します。

コード8行目からは、タブがクリックされると実行する関数となります。関数内では、classの値tabactionをもつタブに対し、tabactionの値を消去します。クリックしたタブに対してclassの値tabactionを追加します。
こうする事で、クリックしたタブにtabactionのCSSが適用されます。
##クリックした時にインデックスのコンテンツを表示
コード13行目からは、コンテンツclassにmenyの値をもつ要素の中で、classの値show display:block;を適用する要素に対し、showの値を消去、非表示となります。
クリックしたタブからインデックス番号を取得して、その番号を使って指定したコンテンツに、classの値showを追加します。
これで、クリックしたタブのインデックス番号と同じインデックス番号のコンテンツが表示されるようになります。
以下JavaScriptコード例

```javascript
document.addEventListener('DOMContentLoaded', function(){
	// タブにクリックイベントを適用
	const tabs = document.getElementsByClassName('tab');
	for(let i = 0; i < tabs.length; i++) {
		tabs[i].addEventListener('click', tabSwitch);
	}
	// タブクリックで実行する関数
	function tabSwitch(){
		// タブclassの値を変える
		document.getElementsByClassName('tabaction')[0].classList.remove('tabaction');
		this.classList.add('tabaction');
		// コンテンツclassの値を変える
		document.getElementsByClassName('show')[0].classList.remove('show');
		const arrayTabs = Array.prototype.slice.call(tabs);
		const index = arrayTabs.indexOf(this);
		document.getElementsByClassName('meny')[index].classList.add('show');
	};
});
```
##おまけ ES2020で追加された個人的に気になったもの
ES2020で追加された最新のJavaScriptの機能でglobalThisというものがありました。
これは、ウェブブラウザでもNode.jsもグローバルオブジェクトを参照できるというもので、ウェブブラウザの処理とNode.jsの処理で共通のコードを使いたいときに便利な機能です。
JavaScriptは、ウェブブラウザだけでなくNode.jsでも実行されます。しかし、グローバルオブジェクトを参照したい場合、ウェブブラウザではwindowがグローバルオブジェクト、Node.jsではglobalがグローバルオブジェクトなので、コードを共通化できなかったようです。
しかし、globalThisを使えば、ウェブブラウザ・Node.jsに共通でグローバルオブジェクトを参照でき、コードを共通化する事ができます。

```html
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script>
      // globalThisの値を出力
      console.log(globalThis);
    </script>
  </head>
  <body></body>
</html>
```
上記のようにし、HTMLファイルをChromeで開くと、コンソールに出力されます。これで、globalThisによって、Windowが出力されていることがわかるようです。