10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WebAssemblyの勉強、GolangでTodoListを作成してみた

Last updated at Posted at 2019-02-24

参考

バージョン

  • macOS Mojave Version 10.14.3
  • go version go1.11.5 darwin/amd64

ソースコード

最終的に作ったコードはこちらです

Hello World

main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello wasm!")
}
bash
GOARCH=wasm GOOS=js go build -o test.wasm main.go

wasmの動作サンプルがgoのインストールディレクトリにあったのでそれを使いました

bash
sudo cp /usr/local/go/misc/wasm/wasm_exec.html .
sudo cp /usr/local/go/misc/wasm/wasm_exec.js .
sudo chmod 666 wasm_exec.html wasm_exec.js

簡単にサーバーを作成

server.go
package main

import (
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(http.Dir("./")))
    http.ListenAndServe(":8080", nil)
}
bash
go run server.go 

http://localhost:8080/wasm_exec.html にアクセスし、Runボタンを押すとgoでWebAssemblyを動かせたのを確認できました

image.png

このサンプルの実行環境を元に、TodoListを作っていこうと思いますm(_ _)m

TodoList作成

wasm_exec.html
<!doctype html>
<html>

<head>
	<meta charset="utf-8">
	<title>Go wasm</title>
</head>
<body>
	<form action="" method="post" id="add">
		<input type="text" id="addText">
		<input type="submit" value="submit" id="">
	</form>

	<ul id="todos"></ul>

	<template id="todo">
		<li>
			<input type="checkbox" name="" class="todoCheck">
			<span class="todoBody">予定ホゲホゲ</span>
			<a href="#" class="todoDelete">delete</a>
		</li>
	</template>

	<script src="wasm_exec.js"></script>
	<script>
		const go = new Go();
		let mod, inst;
		WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then(async (result) => {
			mod = result.module;
			inst = result.instance;
			await go.run(inst);
		});
	</script>
</body>
</html>
main.go
package main

import (
	"syscall/js"
)

func load() {
	document := js.Global().Get("document")
	templateElement := document.Call("getElementById", "todo").Get("content")
	
	document.
		Call("getElementById", "add").
		Call("addEventListener", "submit", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
			if(document.Call("getElementById", "addText").Get("value").String() == "") {
				return
			}

			// 新しいtodo用のDOMを作成
			cloneElement := templateElement.Call("cloneNode", true)

			// チェックボックスのイベント設定
			cloneElement.
				Call("querySelector", ".todoCheck").
				Call("addEventListener", "change", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
					e.Get("target").
						Get("parentNode").
						Call("querySelector", ".todoBody").
						Get("style").
						Set("text-decoration", map[bool]string{true: "line-through", false: "none"}[e.Get("target").Get("checked").Bool()])
				}))
		
			// todoの内容を設定
			cloneElement.
				Call("querySelector", ".todoBody").
				Set("textContent", document.Call("getElementById", "addText").Get("value").String())

			// 削除イベントを設定
			cloneElement.
				Call("querySelector", ".todoDelete").
				Call("addEventListener", "click", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
					if(js.Global().Get("confirm").Invoke("削除しますか?").Bool()) {
						e.Get("target").
							Get("parentNode").
							Call("remove")
					}
				}))

			// 新しいtodoをhtmlに表示
			document.Call("getElementById", "todos").Call("appendChild", cloneElement)

			// 入力ボックスを空にしておく
			document.Call("getElementById", "addText").Set("value", "")
		}))
}

func main() {
	c := make(chan struct{}, 0)

	println("WASM Go Initialized")
	load()
	<-c
}

pY6F3POETq.gif

なんとかtodolistを作るまでできました。

最後まで見ていただいてありがとうございましたm(_ _)m

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?