[GopherJS] HTML Web History API Example


Change browser URL without reloading the whole web page - only partially update the content of the web page, improve the user experience of visiting your website. This is done via HTML history API and GopherJS.

I simplify the example in the tutorial of CSS-Tricks [4]. In the example below, I create three links, and if users click the link, the browser URL will change, and update the texts correspondingly without reloading. When users move backward or forward through the history, web page will also be partially updated.

Demo

index.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>GopherJS HTML History API Demo</title>
</head>
<body>

<div><a class="person" href="/p1/" data-content="content of person 1">person 1</a></div>
<div><a class="person" href="/p2/" data-content="content of person 2">person 2</a></div>
<div><a class="person" href="/p3/" data-content="content of person 3">person 3</a></div>
<hr>
<div id="info">Entry Page</div>

<script src="app.js"></script>
</body>
</html>
app.go | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Google Search: html history api
// https://css-tricks.com/using-the-html5-history-api/
package main

import "github.com/gopherjs/gopherjs/js"

var history = js.Global.Get("history")

func main() {
	d := js.Global.Get("document")
	info := d.Call("getElementById", "info")
	nodeList := d.Call("querySelectorAll", ".person")
	length := nodeList.Get("length").Int()
	for i := 0; i < length; i++ {
		// get i-th element in nodelist
		elm := nodeList.Call("item", i)

		elm.Call("addEventListener", "click", func(event *js.Object) {
			event.Call("preventDefault")

			href := elm.Call("getAttribute", "href").String()
			content := elm.Get("dataset").Get("content").String()
			history.Call("pushState", content, nil, href)
			info.Set("innerHTML", content)
		})
	}

	js.Global.Call("addEventListener", "popstate", func(event *js.Object) {
		if event.Get("state") == nil {
			info.Set("innerHTML", "Entry Page")
		} else {
			info.Set("innerHTML", event.Get("state").String())
		}
	})
}

To see demo: use GopherJS to compile app.go to app.js. Put index.html and app.js in the same directory. Open index.html with your browser.

For JavaScript verson, see [7].


Tested on:

  • Ubuntu Linux 16.10
  • Go 1.7.4
  • Chromium Version 55.0.2883.87 Built on Ubuntu , running on Ubuntu 16.10 (64-bit)

References:

[1]GopherJS - A compiler from Go to JavaScript (GitHub, GopherJS Playground, godoc)
[2]

html history api - Google search

html history api - DuckDuckGo search

html history api - Bing search

html history api - Yahoo search

html history api - Baidu search

html history api - Yandex search

[3]Manipulating the browser history - Web APIs | MDN
[4]Using the HTML5 History API | CSS-Tricks
[5][Golang] GopherJS DOM Example - Access HTML Data Attribute
[6][Golang] undefined Test in GopherJS
[7][JavaScript] HTML Web History API Example