[Work/Class/ES2015で動的Webアプリ/es2015_basic]

ES2015の基本 - PromiseとXMLHttpRequestを使ったAjaxとfetch / 2018-07-13 (金)

XMLHttpRequestクラスとそのインスタンス

簡単に言えば,インタラクティブに他のページや画像などを持ってきて,今のページに表示させるためのクラスである.

Promiseクラスのオブジェクトを生成するように設計してやると,「読み込み終わって,結果が正しい時に,次のコードを実行する」という処理ができる.

Cross-Originポリシーの関係で,XMLHttpRequestクラスのインスタンスは,そのJavaScriptファイルが置いてあるドメインからしかAjaxできない.(正確には色々やればできるが面倒臭い)

コード例

htmlを取得して,その結果をテキストとしてdivに表示する.

実行ページ

Cross-Originポリシーの関係で,XMLHttpRequestクラスのオブジェクトは,そのJavaScriptファイルが置いてあるドメインからしかAjaxできない.(できるが面倒臭い)

<!DOCTYPE html>
<!-- PromiseAjaxWithClass.html -->
<html lang="ja">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta charset="utf-8">
    <title>Promiseを使ってAjax</title>
    
    <script type="text/javascript" src="./PromiseAjaxWithClass.js">
    </script>
  </head>
  <body>
    <p>取得したいHTMLのURLを記入</p>
    <form>
      <input type="text" name="target_url" value="http://cad.lolipop.jp/" />
      <input type="button" name="send_button" value="取得" onclick="getHtml(this.form.elements['target_url'].value)" />
    </form>
    <div id="display_iframe">
      ここに取得してきたものが表示されます.
    </div>
  </body>
</html>
// PromiseAjaxWithClass.js
'use strict';
class MyAjax{
    constructor(targetUrl){
	this.targetUrl = targetUrl;
	this.gottenHtmlPage = '';
    }

    setTargetUrl(targetUrl){
	this.targetUrl = targetUrl;
    }

    setDisplayingDivId(divId){
	this.divId = divId;
    }

    // AjaxによるHTMLページの取得を実行する関数 Promiseを返す
    startHttpRequest(){
	return new Promise((resolve, reject) => {
	    let xmlHttpRequest = new XMLHttpRequest();
	    //open(HTTPメソッド, URL, 非同期モードかどうか, ユーザ名, パスワード)
	    xmlHttpRequest.open('GET', this.targetUrl, true);
	    xmlHttpRequest.onload = () => {
		if(xmlHttpRequest.status >= 200 && 
		   xmlHttpRequest.status < 300){
		    resolve(xmlHttpRequest.responseText);
		}
		else{
		    reject(xmlHttpRequest.status);
		}
	    };
	    xmlHttpRequest.onerror = () => {
		reject(xmlHttpRequest.status);
	    };
	    //設定が終わった後にsend(null)を実行すると取得が始まる.
	    xmlHttpRequest.send(null);
	});
    }

    // AjaxによるHTMLページの取得が完了した時に呼び出すコールバック関数
    whenFinishSuceed(result){
	document.getElementById('display_iframe').innerText = result;
    }

    whenFinishFailed(err){
	document.getElementById('display_iframe').innerHTML = 
	    '<p>' + 'Faild to get WebPage. Error code is: ' + err + '</p>';
    }
}

window.getHtml = (targetUrl) => {
    window.myAjax.setTargetUrl(targetUrl);
    window.myAjax.startHttpRequest()
	.then(window.myAjax.whenFinishSuceed)
	.catch(window.myAjax.whenFinishFailed);
};

window.addEventListener('load', () => {
    window.myAjax = new MyAjax('http://cad.lolipop.jp/');
    window.myAjax.setDisplayingDivId('display_iframe');
    window.myAjax.startHttpRequest()
	.then(window.myAjax.whenFinishSuceed)
	.catch(window.myAjax.whenFinishFailed);
});

fetch API

とまぁ,自分で実装すると面倒臭いことこの上ないのだが,Promiseのインスタンス(オブジェクト)を返す全く同じ機能がfetch関数として既に標準ライブラリとして実装されており,Chromeでは問題なくXMLHttpRequestクラスの代わりとして使用できる.

おまけに,Cross-Originポリシーも(サーバが対応していれば)一行設定を書いてやるだけで無視することができる.

コード例

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>Fetch API Test</title>
    <script type="text/javascript">
      window.addEventListener('load',  () => {
	  fetch('http://cad.lolipop.jp/', { // 取得するデータのURL
	      method: 'GET',
	      mode: 'cors', //Cross-Originポリシーを無視する
	      credentials: 'same-origin' // 認証がある時はこのオプションを指定
	  }).then((response) => {
	      return response.text()
	  }).then((text) => {
	      document.getElementById('for_display').innerText = text;
	  }).catch((error) => {
	      console.log(error);
	  });
      });
    </script>
  </head>
  <body>
    <div id="for_display">
    </div>
  </body>
</html>

[Work/Class/サウンドトラック制作基礎/setup]

FL Studioのダウンロードとインストール

バージョン違いは適宜読み替えること.

FL Studioのダウンロード

http://www.image-line.com/downloads/flstudiodownload.htmlへ行く.

ダウンロード画面

Windows版をダウンロード.

FL Studioのインストール

down_mini1.jpg

ダウンロードしたファイルをダブルクリック.(ダウンロードしたバージョンの名前がついている).
以下はダウンロードしたバージョンや時期,ダウンロードサイトによって多少変わってくるので,適宜対応する事.
FL Studio本体がインストールされていれば,とりあえず授業に問題はない.

down_mini1.jpg

「Next」

down_mini1.jpg

「I Agree」

down_mini1.jpg

「All users」にチェックが入っている事を確認して「Next」

down_mini1.jpg

FL Studio本体やプラグインの他に「Aiso4All」にチェックが入っている事を確認して「Next」

down_mini1.jpg

Destination Folder(インストールされるフォルダ)は変更しないで「Next」

down_mini1.jpg

同様にDestination Folder(インストールされるフォルダ)は変更しないで「Next」

down_mini1.jpg

Baiduやその他のプログラムをインストールするか訊かれる場合は,「インストールしない」を選択して「Next」

down_mini1.jpg

「Install」

down_mini1.jpg

ASIO4ALLのインストール.「Next」

down_mini1.jpg

「I accept …」にチェックを入れて「Next」

down_mini1.jpg

ASIO4ALL以外は入れなくても良いので「Next」

down_mini1.jpg

Destination Folderは変更せずに「Install」

down_mini1.jpg

ASIO4ALLのインストール終了.「Finish」

down_mini1.jpg

この画面が出たら,そのまま「Next」で問題ない.

down_mini1.jpg

この画面も宣伝なので,そのまま「Next」で飛ばしてしまって構わない.

down_mini1.jpg

「Run FL Studio (ヴァージョン)」にチェックが入っている事を確認し,「Finish」

down_mini1.jpg

FL Studioが起動する.


[Work/Class/サウンドトラック制作基礎/setup]

FL Studioのダウンロードとインストール(Mac用)

FL Studioのダウンロード

http://www.image-line.com/downloads/flstudiodownload.htmlへ行く.

ダウンロード画面

Mac版をダウンロード.

FL Studioのインストール

ダウンロードされたインストーラのディスクイメージ

ダウンロードされたディスクイメージ.

ディスクイメージをダブルクリックしてマウントするとインストーラが出る.

ディスクイメージをダブルクリックしてマウントするとインストーラが出る.

インストーラをダブルクリックしてインストール開始

インストーラをダブルクリックしてインストール開始.

確認 確認 ユーザ認証

普通に管理者ユーザ認証.

インストール中 インストール完了

インストール完了

インストーラの削除確認

インストーラの削除確認.どちらでも.

インストールされている

アプリケーションを見るとインストールされている.

起動

起動.

以下は以前のベータ版のインストール方法.

FL Studio Mac用Beta版

Macにはまだ正式版がないので,Macで作業したい人はBeta版を用いる.(ユーザ登録などの細かいことについては,自分で行うこと.

http://www.image-line.com/downloads/flstudiodownload.htmlへ行く.

ダウンロードページからBeta版を選択

ダウンロードページからBeta版を選択.

フォーラムへ行く

フォーラムへ行く.(あらかじめユーザ登録は済ませておくこと)

フォーラムの中からトピックを選択

フォーラムの中から,Beta版のトピックを選択.

インストーラをダウンロード

インストーラをダウンロード.

ダウンロードしたインストーラのイメージをダブルクリックするとインストーラパッケージが出てくる

ダウンロードしたイメージ(.img)をダブルクリックしてマウントすると,インストーラパッケージ(.pkg)が出てくるので,これを実行.

インストーラが起動

インストーラが起動するので「続ける」.

インストーラでインストール

「インストール」

インストール中

インストール中

インストール完了

インストールが完了したら「閉じる」.

インストール完了

インストールが完了したら「閉じる」.

インストールされている

/Applicationsの中に「FL Studio Mac Beta」が入っているので,起動.

起動成功

起動成功.


[Work/Class/Google Maps APIの基礎/basic]

GoogleMaps APIの基礎 - マーカの情報をCSVから持ってくる

マーカーを大量に描画しようとする時,全てJavaScriptで書き下すのは非常に面倒くさい.そこでExcelやGoogleスプレッドシートで2次元テーブルの形でデータを作っておき,それをCSV形式でサーバにおいておき,それを読み込んできてマーカの情報として表示する.

CSVデータの読み込みには非同期処理(AJAX)を使う.XMLHttpRequestを使ったAjaxとfetchを参考にすること.

自販機とそこで売っている飲み物をまとめたCSVファイル vendor_data.csv は以下の通り

飲み物名称\自販機ID,m001,m002,m003,m004,m005,m006,m007,m008,m009,m010
すべて,1,1,1,1,1,1,1,1,1,1
FIRE,0,0,1,0,0,1,1,0,0,0
BOSS,0,0,0,0,1,0,0,0,1,0
GEORGIA,0,0,0,1,0,1,0,0,0,0
DyDo,0,0,1,0,0,0,1,1,0,0
WONDA,1,0,0,0,0,1,0,0,0,1
TULLY'S,0,1,0,0,0,0,0,0,0,0
ココア,0,0,0,0,0,0,0,1,0,0
生茶,0,0,1,0,0,0,1,0,0,0
麦茶,0,1,1,0,1,0,1,1,1,0
レモンティー,0,0,1,1,0,0,0,1,0,0
ミルクティー,1,0,1,0,1,0,1,1,1,0
爽健美茶,0,0,0,0,0,1,0,0,0,0
綾鷹,0,0,0,1,0,1,0,0,0,0
伊右衛門,0,0,0,0,1,0,0,0,1,0
自販機lat,35.61298,35.612963,35.613368,35.613168,35.613184,35.612488,35.610865,35.617523,35.617498,35.617628
自販機long,139.381036,139.381059,139.381978,139.381584,139.381563,139.382121,139.383056,139.385693,139.385877,139.386235

表示ボタンを配置してマーカ描画関数を呼び出すhtmlファイル vendor_map.html と,JavaScriptファイル fetc_csv.js

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>自販機をGoogle Mapsにマッピングする</title>
    <!-- Google Maps APIをWeb上から読んでくる -->
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
    <!-- 自分で作ったJSファイル -->
    <script type="text/javascript" src="./fetch_csv.js"></script>

        <!-- とりあえずCSSを直接書いてしまう -->
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #map {
            /*
             div id=mapになってるdiv
             ここに地図
             高さ500ピクセル,幅は上位のdiv(ここではbody)の50%
            */
            height: 500px;
            width: 50%;
        }
    </style>

  </head>
  <body>
    <div id="select_button">
      <input type="button" value="全ての自販機" onclick="drawMarkers(0)" />
      <input type="button" value="キリンFIRE" onclick="drawMarkers(1)" />
      <input type="button" value="サントリーBOSS" onclick="drawMarkers(2)" />
      <input type="button" value="GEORGIA" onclick="drawMarkers(3)" />
      <input type="button" value="DyDo" onclick="drawMarkers(4)" />
      <input type="button" value="WONDA" onclick="drawMarkers(5)" />
      <input type="button" value="TULLY's" onclick="drawMarkers(6)" />
      <input type="button" value="ココア" onclick="drawMarkers(7)" />
      <input type="button" value="生茶" onclick="drawMarkers(8)" />
      <input type="button" value="麦茶" onclick="drawMarkers(9)" />
      <input type="button" value="レモンティー" onclick="drawMarkers(10)" />
      <input type="button" value="ミルクティー" onclick="drawMarkers(11)" />
      <input type="button" value="爽健美茶" onclick="drawMarkers(12)" />
      <input type="button" value="綾鷹" onclick="drawMarkers(13)" />
      <input type="button" value="伊右衛門" onclick="drawMarkers(14)" />

    </div>

    <div id="map"></div>
  </body>
 </html>
'use strict';
window.addEventListener('load', () => {
  // 地図の表示
  // ここから地図を表示する
  //地図表示に必要なパラメータを保持するconstオブジェクト
  const mapElement = {
// 南大沢駅の緯度経度を中心にして表示する
      center: {lat:35.614349, lng:139.379774},
      // ズームレベル
      zoom: 16
  };

  // 地図を保持するためのconstオブジェクトmyMapを宣言し,
  // GoogleMapsのコンストラクタの引数に,先に定義した地図表示に必要なパラメータを食わせる
  window.myMap =
      new google.maps.Map(document.getElementById('map'), mapElement);
  // コンストラクタが実行されると表示される


  // CSVデータを非同期で持ってくる
  fetch('./vendor_data.csv', {
    method: 'GET',
    mode: 'cors', //クロスオリジンポリシーを無視する
    credentials: 'same-origin' // 認証がある時はこのオプションを指定しておく
  }).then((response) => {
    // 成功したら,取得したファイルをテキストとして,次のthenに回す
    return response.text();
  }).then((text) => {
    // テキストデータとしてきた内容から,必要なデータを組み立てる
    // 読み込んだデータを1行ずつ格納する配列をグローバルで宣言する
  	window.drinkName = new Array();
  	window.drinkData = new Array();
  	window.latArray = new Array();
  	window.longArray = new Array();

  	// 読み込んだCSVデータの名前を変える
  	let csvData = text;

  	// CSVの全行を取得
    // 「改行」でスプリットすると,1行を単位とした配列に分かれる
  	let lines = csvData.split("\n");

  	for (let i = 0; i < lines.length; i++) {
  	    // 1行ごとの処理

  	    if (i >= 1 && i <= 15) { // 0行目を飛ばして,1行目から20行目まで
          // 1行をカンマでスプリットすると,CSVの1要素になる
  		    let aDrinkSet = lines[i].split(",");
  		    window.drinkName.push(aDrinkSet[0]);
  		    window.drinkData.push(aDrinkSet.slice(1));
  	    }
  	    else if (i == 16) { // 18行目はlat(緯度)
  		    window.latArray = lines[i].split(",").slice(1);
  	    }
  	    else if (i == 17) { // 19行目はlng(軽度)
  		    window.longArray = lines[i].split(",").slice(1);
  	    }
  	}


    // マーカを格納する配列を初期化する
    window.currentMarkerSet = new Array();

    // 飲み物のマーカーを表示する
    // 最初は0番目「全て」の自販機の意味
    drawMarkers(0);

  }).catch((error) => {
    // 何かエラーが起きたら,そのエラーコードを表示する
    alert("<p>" + "Faild to get CSV. Error code is: " + error + "</p>");
  });
});

function drawMarkers(drinkNumber){

    // まず最初に既表示のマーカーを消す
    for(let i=0; i< window.currentMarkerSet.length; i++){
	     window.currentMarkerSet[i].setMap(null);
    }
    window.currentMarkerSet = new Array();

    // マーカーを作る
    let aDrinkSet = window.drinkData[drinkNumber];
    for(let i=0; i<aDrinkSet.length; i++){
	     if(Number(aDrinkSet[i]) == 1){
	     let aVenderMarker = new google.maps.Marker({
		       position: {lat: Number(window.latArray[i]), lng: Number(window.longArray[i])},
		         map: window.myMap
	     });
	     window.currentMarkerSet.push(aVenderMarker);
	    }
    }
}

[Work/Class/Google Maps APIの基礎]

Google Maps API 授業資料