Skip to content
/ godom Public

Make DOM manipulation in Go as similar to JavaScript as possible. (via GopherJS or WebAssembly)

License

Notifications You must be signed in to change notification settings

siongui/godom

Repository files navigation

https://api.travis-ci.org/siongui/godom.svg?branch=master https://goreportcard.com/badge/github.com/siongui/godom

https://img.shields.io/twitter/url/https/github.com/siongui/godom.svg?style=social

Make DOM Manipulation in Go as similar to JavaScript as possible via GopherJS. For DOM Manipulation via WebAssembly, visit wasm directory.

Because the code written directly by GopherJS without any wrapper is really ugly. For example, if you want to getElementById, you need to write:

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

foo := js.Global.Get("document").Call("getElementById", "foo")

With godom, you write:

import (
      . "github.com/siongui/godom"
)

foo := Document.GetElementById("foo")

which looks like JavaScript and more readable.

Why not use existing go-js-dom?

Because it's too restricted, and sometimes need to do a lot of type casting. For example, if you have an audio element with id foo and you want to call the Play() method, you need to write the following code:

import (
      "honnef.co/go/js/dom"
)

a := dom.GetWindow().Document().GetElementByID("foo").(*dom.HTMLAudioElement)
a.Play()

If you use querySelectorAll to select a lot of such elements, you need to do a lot of type casting, which is really disturbing.

With godom, you can write like this:

import (
      . "github.com/siongui/godom"
)

a := Document.GetElementById("foo")
a.Play()

godom is only a wrapper for GopherJS. If something is not implemented, you can still use the GopherJS methods to call or get the method/property you need. For example, if the Play() method of the audio element is not implemented, you can use GopherJS Call method to call play method directly:

import (
      . "github.com/siongui/godom"
)

a := Document.GetElementById("foo")
a.Call("play")

Test if event.state is null in popstate event listener:

ih := Document.QuerySelector("#infoHistory")

Window.AddEventListener("popstate", func(e Event) {
        if e.Get("state") == nil {
                ih.SetInnerHTML("Entry Page")
        } else {
                ih.SetInnerHTML(e.Get("state").String())
        }
})

Assume we have the following element:

<p id="foo" data-content="content of person 1"></p>

You can access the data-content as follows:

p := Document.QuerySelector("#foo")
content := p.Dataset().Get("content").String()

We will transform Tipitaka XML to HTML and append it to the following div.

<div id="xml"></div>

The frontend code:

// Basic Example - XSLT: Extensible Stylesheet Language Transformations | MDN
// https://developer.mozilla.org/en-US/docs/Web/XSLT/XSLT_JS_interface_in_Gecko/Basic_Example
xsltProcessor := NewXSLTProcessor()

// Load the xsl file using synchronous (third param is set to false) XMLHttpRequest
myXMLHTTPRequest := NewXMLHttpRequest()
//myXMLHTTPRequest.Open("GET", "https://tipitaka.org/romn/cscd/tipitaka-latn.xsl", false)
myXMLHTTPRequest.Open("GET", "https://siongui.github.io/tipitaka-romn/cscd/tipitaka-latn.xsl", false)
myXMLHTTPRequest.Send()

xslStylesheet := myXMLHTTPRequest.ResponseXML()

// Finally import the .xsl
xsltProcessor.ImportStylesheet(xslStylesheet)

// load the xml file
myXMLHTTPRequest2 := NewXMLHttpRequest()
//myXMLHTTPRequest.Open("GET", "https://tipitaka.org/romn/cscd/vin01m.mul0.xml", false)
myXMLHTTPRequest2.Open("GET", "https://siongui.github.io/tipitaka-romn/cscd/vin01m.mul0.xml", false)
myXMLHTTPRequest2.Send()

xmlDoc := myXMLHTTPRequest2.ResponseXML()

fragment := xsltProcessor.TransformToFragment(xmlDoc, Document)

Document.GetElementById("xml").AppendChild(fragment)

This example show you how to register onclick event handler via HTML onclick attribute.

HTML:

<div onclick="myhandler('Hi')">Click me to say Hi<div>

Go/GopherJS:

Document.Set("myhandler", func(s string) {
      Alert(s)
})

Before using Element.getAttribute(), call Element.hasAttribute() first to check if the attribute exists or not. Otherwise something unexpected will happen.

Released in public domain. See UNLICENSE.

[1]GopherJS - A compiler from Go to JavaScript (GitHub, GopherJS Playground, godoc)
[2]dom - GopherJS bindings for the JavaScript DOM APIs (GitHub)
[3]
[4][Golang] Add Method to Existing Type in External Package
[5]JavaScript Remove All Children of a DOM Element
[6]How to do insert After() in JavaScript without using a library? - Stack Overflow
[7]

javascript element position

javascript - Retrieve the position (X,Y) of an HTML element - Stack Overflow

[8]

javascript check class exists - Google search

javascript - Test if an element contains a class? - Stack Overflow

[9]
[10]Go Report Card | Go project code quality report cards
[11]Shields.io: Quality metadata badges for open source projects
[12]HTML DOM Style object
[13]

About

Make DOM manipulation in Go as similar to JavaScript as possible. (via GopherJS or WebAssembly)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages