Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/siongui/godom

Make DOM manipulation in Go as similar to JavaScript as possible. (via GopherJS or WebAssembly)
https://github.com/siongui/godom

dom-manipulation frontend go golang gopherjs

Last synced: about 23 hours ago
JSON representation

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

Awesome Lists containing this project

README

        

==========================
`DOM Manipulation`_ in Go_
==========================

.. image:: https://img.shields.io/badge/Language-Go-blue.svg
:target: https://golang.org/

.. image:: https://godoc.org/github.com/siongui/godom?status.svg
:target: https://godoc.org/github.com/siongui/godom

.. image:: https://api.travis-ci.org/siongui/godom.svg?branch=master
:target: https://travis-ci.org/siongui/godom

.. image:: https://goreportcard.com/badge/github.com/siongui/godom
:target: https://goreportcard.com/report/github.com/siongui/godom

.. image:: https://img.shields.io/badge/license-Unlicense-blue.svg
:target: https://raw.githubusercontent.com/siongui/godom/master/UNLICENSE

.. image:: https://img.shields.io/badge/Status-Beta-brightgreen.svg

.. image:: https://img.shields.io/twitter/url/https/github.com/siongui/godom.svg?style=social
:target: https://twitter.com/intent/tweet?text=Wow:&url=%5Bobject%20Object%5D

Make `DOM Manipulation`_ in Go_ as similar to JavaScript_ as possible via
GopherJS_. For DOM Manipulation via WebAssembly_, visit wasm_ directory.

- `Ubuntu 20.04`_
- Go_

.. contents:: **Table of Content**

Why?
++++

Why not use GopherJS directly?
##############################

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

.. code-block:: go

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

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

With *godom*, you write:

.. code-block:: go

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:

.. code-block:: go

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:

.. code-block:: go

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

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

What if the method/property is not implemented in *godom*?
##########################################################

*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:

.. code-block:: go

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

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

Code Example
++++++++++++

- `Frontend Programming in Go`_: If you have no experience of GopherJS before,
read this.
- `Synonyms - Go and JavaScript`_: If you have some experience about GopherJS,
this serves as references for quick start.

null test
#########

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

.. code-block:: go

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())
}
})

HTML dataset (data-* attribute)
###############################

Assume we have the following element:

.. code-block:: html

You can access the ``data-content`` as follows:

.. code-block:: go

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

XML/XSLT
########

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

.. code-block:: html

The frontend code:

.. code-block:: go

// 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)

HTML onevent Attribute
######################

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

**HTML**:

.. code-block:: html

Click me to say Hi

**Go/GopherJS**:

.. code-block:: go

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

`Element.getAttribute()`_
#########################

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

UNLICENSE
+++++++++

Released in public domain. See UNLICENSE_.

References
++++++++++

.. [1] `GopherJS - A compiler from Go to JavaScript `_
(`GitHub `__,
`GopherJS Playground `_,
|godoc|)

.. [2] `dom - GopherJS bindings for the JavaScript DOM APIs `_
(`GitHub `__)

.. [3] | `panic: interface conversion: ast.Expr is *ast.SelectorExpr, not *ast.Ident - Google search `_
| `add a method to an external package - Google search `_

.. [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] | `Who is using GopherJS? : golang `_
| `GopherJS 1.8-1 is released : golang `_

.. [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] | `javascript is focused - Google search `_
| `javascript is focused - DuckDuckGo search `_
| `javascript is focused - Ecosia search `_
| `javascript is focused - Qwant search `_
| `javascript is focused - Bing search `_
| `javascript is focused - Yahoo search `_
| `javascript is focused - Baidu search `_
| `javascript is focused - Yandex search `_

.. _DOM Manipulation: https://www.google.com/search?q=DOM+Manipulation
.. _Go: https://golang.org/
.. _JavaScript: https://www.google.com/search?q=JavaScript
.. _GopherJS: https://github.com/gopherjs/gopherjs
.. _WebAssembly: https://duckduckgo.com/?q=webassembly
.. _wasm: wasm
.. _Ubuntu 20.04: https://releases.ubuntu.com/20.04/
.. _Go 1.8: https://golang.org/dl/
.. _go-js-dom: https://github.com/dominikh/go-js-dom
.. _UNLICENSE: https://unlicense.org/
.. _Frontend Programming in Go: https://siongui.github.io/2017/12/04/frontend-programming-in-go/
.. _Synonyms - Go and JavaScript: https://siongui.github.io/2017/12/07/synonyms-go-and-javascript/
.. _HTML onclick attribute: https://www.google.com/search?q=HTML+onclick+attribute
.. _Element.getAttribute(): https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
.. _Element.hasAttribute(): https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttribute

.. |godoc| image:: https://godoc.org/github.com/gopherjs/gopherjs/js?status.png
:target: https://godoc.org/github.com/gopherjs/gopherjs/js