【javascript】アップロードファイルのプレビュー

<form action="/post" method="post" enctype="multipart/from-data">
    <div>
        <input type="file" name="test" onchange="previewFile(this);">
    </div>
    <div>
        <input type="submit" value="送信する">
    </div>
</form>
<p>プレビュー</p>
<img id="preview" width="100px" height="100px">

<script>
function previewFile(file) {
    var fileData = new FileReader();
    fileData.onload = (function() {
        document.getElementById('preview').src = fileData.result;
    });
    fileData.readAsDataURL(file.files[0]);
}
</script>

次はaxumでデータのやり取りだな

【Rust】AxumでCSS, JSなどstaticファイルを使いたい時

tower-http = { version = “0.6.2”, features = [“fs”] }

staticフォルダにcssファイルを置きます。
static/styles.css

h1 {
    color:red;
}

template/test.html

<head>
    <title>title</title>
    <link rel="stylesheet" href="styles.css">
</head>
<h1>Hello world</h1>

main.rs

use tower_http::services::{ServeDir, ServeFile};
use axum::{
    routing::get,
    Router,
};

#[tokio::main]
async fn main() {

    let serve_dir = ServeDir::new("static").not_found_service(ServeFile::new("static"));

    let app = Router::new()
        .route("/", get(handle_index))
        .nest_service("/static", serve_dir.clone())
        .fallback_service(serve_dir);

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn handle_index()-> axum::response::Html<String> {
    let tera = tera::Tera::new("templates/*").unwrap();

    let mut context = tera::Context::new();
    context.insert("title", "Index page");

    let output = tera.render("test.html", &context);
    axum::response::Html(output.unwrap())
}

なるほど、これでCSSもjsも自由にコーディングできますね。

javascriptのsplitメソッド

splitは指定した文字列または正規表現によって文字列が分割され、結果が配列になって帰って来る

var str = "あ、い、う";
console.log(str.split("、"));

$ node main.js
[ ‘あ’, ‘い’, ‘う’ ]

正規表現

console.log(str.split(/[0-9]./));

区切り文字を残す場合

var str = "あ、い、う";
console.log(str.split(/(?<=、)/g));

()で囲まれていると残り、囲まれていないと削除

console.log(str.split(/(、)/));

$ node main.js
[ ‘あ’, ‘、’, ‘い’, ‘、’, ‘う’ ]

jsのrequireの使い方

分割した機能ごとのjsファイルのことをモジュールと呼ぶ
importを使うのがESM方式(ECMAScript Module)で、requireを使うのがCJS(CommonJS Modules)

### import文の書き方
モジュール側

export const helloWorld = function() {
    console.log('Hello World!');
}

読み込み側

import { helloWorld } from './module'

helloWorld();

### require
モジュール側
L module.exportsと書く

module.exports = function() {
    console.log('hello world!');
}

読み込み側
 L require文を使って先ほどのモジュールを読み込む

const helloWorldModule = require('./module.js');

helloWorldModule();

$ sudo apt install nodejs
$ node main.js
hello world!

読み込まれる方でmodule.export()とするのが鍵ですね。

JavaScriptでjsonを表示する

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
	<ul id="list">
<!-- ここに出力します -->
	</ul>
	<script>
		$(function(){
			json = "./list.json";
			target = $("#list");
			$.getJSON(json, function(data, status){
				for(var n in data){
					var text = '<li>';
					if (data[n].url){
						line = '<a href="'+data[n].url+'" target="_blank"><span>'+data[n].name+'</span></a>';
					} else {
						line = '<i><span>'+data[n].name+'</span></i>';
					}
					text = text+line+'</li>';
					$(target).append(text);
				}
			})
		})
	</script>
</body>
</html>

これは分かり易いですね。

チャット返答のJavaScript側の処理を考える

チャットの返答前に処理一覧を表示させたいので、Promiseで以下のように書ければ良い

	console.log("処理開始");

	new Promise((resolve, reject)=> {
		console.log("送信者のメッセージをDBへインサート処理");
		list();
		setTimeout(function(){
			resolve();
		}, 2000);
	}).then(function(value){
		console.log("API回答メッセージをDBへインサート処理");
		list();
	}).catch((data) => console.log(data)
	).finally(() => console.log("処理終了"));

	async function list(){
		console.log("DBからリストを表示");
	}

あとは(1)JavaScriptからPHP側にデータをどのように送るか、(2)DBからデータを取得するかを考える

JavaScript Promiseとは

Promiseは処理が問題なく完了すればresolve、反対に問題があればrejectを呼び出してメッセージを表示
コールバックとは、ある関数へ別の関数を渡すこと

sampleFunction1(function(data1){
	sampleFunction2(function(data2){
		// 処理
	})
})
	var sample = new Promise(function(resolve, reject){
		setTimeout(function(){
			resolve();
		}, 1000);
	});

	sample.then(function(value){
		console.log("Promise成功!");
	});

	console.log("先に出力");

Promiseの処理を連結させるものをchainという

JavaScriptの非同期処理

setTimeoutを用いた非同期処理

		console.log(1);
		setTimeout(()=> console.log(2), 5000);
		console.log(3);

1->3->2の順番で処理される

		const sleep = (second) => {
			const startTime = new Date();
			while (new Date() - startTime < second);
			console.log("done sleep");
		}

		const button = document.querySelector("button");

		button.addEventListener("click", () => console.log("clicked"));

		sleep(5000)

処理される順番 : setTimeout実行中に次のタスクが実行される

		const first = () => {
			setTimeout(() => console.log("task1 done"), 2000);
			console.log("function frist done");
		}

		const second = () => console.log("function second done");

		first();
		second();

### Promiseとは?
Promiseとは非同期処理をより簡単かつ可動性が上がるように書けるようにしたJavaScriptのオブジェクト
Promiseは3つの状態がある
– pending: 非同期処理の実行中の状態を表す
– fulfilled: 非同期処理が正常終了した状態を表す
– rejected: 非同期処理が異常終了した状態を表す

new Promise(

).then(

).catch(

).finally(
);

引数としてコールバック関数をとる

new Promise((resolve, reject) => {

}).then(

).catch(

).finally(

);

### resolve
Promiseの状態がfulfilled(正常終了)になったらresolveが実行される
resolveが実行された場合は、thenメソッドが実行される
thenメソッドが実行された場合catchメソッドはm無視され、最後にfinallyメソッドが実行される

new Promise((resolve, reject) => {
	resolve("hoge");
}).then((data)=>console.log(data)

).catch(

).finally(()=>console.log("finally")

);

### reject
Promiseの状態がrejectedになったらrejectが実行される
rejectはPromise内のコールバック実行中に何らかのエラーが発生しそれをPromiseに通知するために使用する関数
rejectが実行される場合はcatchメソッドのコールバック関数が実行される

new Promise((resolve, reject) => reject("fuga")
.then(
).catch((data)=> console.log(data))
.finally(()=>console.log("finally")
);

Promiseオブジェクト内の同期・非同期処理の関係

new Promise((resolve, reject) => {
 // 同期処理
}).then(
 // resolveの実行を待って非同期処理
).catch(
 // rejectの実行を待って非同期処理
).finally(
 // resolveかrejectの実行を待って非同期処理
);
	new Promise((resolve, reject) => {
	 console.log("Promise");
	  resolve();
	}).then(() => console.log("then"));

	console.log("global end");

Promiseオブジェクトを使った並列処理
– Promise.all => 並列処理している全てが完了したら後続処理に続く

	const sleep = (val) => {
		return new Promise((resolve) => {
			setTimeout(() => {
				console.log(val++);
				resolve(val);
			}, 1000);
		});
	};

	Promise.all([sleep(0), sleep(1), sleep(2)]).then(() => console.log("end"));

AsyncとAwait
AsyncとAwaitはPromiseを更に直感的に書けるようにしたもの

– Async
Asyncを使って宣言された関数はPromiseオブジェクトを返却する
関数宣言の先頭にAsyncがついていたらPromiseオブジェクトがreturnされる。thenメソッドにつなげられる。

– Await
AwaitはPromiseを返却する関数の非同期処理が終わるのを待つ記述
Awaitで受けられるものはPromiseのインスタンス

	const sleep = (val) => {
		return new Promise((resolve) => {
			setTimeout(() => {
				resolve(val);
			}, 1000);
		});
	};

	async function init() {
		console.log(await sleep(0));
	}

	init();

fetchという関数
fetchを使うことでサーバからデータを取得できる

	fetch("")
		.then((response) => {
			return response.json();
		})
		.then((json) => {
			console.log(json);
		});

JSの半角→全角変換

<script>
	function zenkaku2Hankaku(str){
		return str.replace(/[A-Za-z0-9]/g, function(s){
			return String.fromCharCode(s.charCodeAt(0) + 0xFEE0);
		});
	}

	console.log(zenkaku2Hankaku("123abC"));
</script>

JSで書く場合も基本はスクリプトの中に辞書を持って変換しているのね。
仕組みを理解した。