+
+
+ Scala-js-dom provides a nice statically typed interface to the DOM such that it can be called from Scala code without resorting to js.Dynamic. All javascript globals functions, singletons and classes are members of the org.scalajs.dom, org.scalajs.dom.html, org.scalajs.dom.svg, etc. packages. For example:
+
+
def main() = {
+ import org.scalajs.dom
+ dom.window.alert("Hi from Scala-js-dom")
+}
+
+
+ Will cause a javascript alert box saying `Hi from Scala-js-dom` to appear. Other javascript classes and objects can be similarly accessed e.g. new dom.XMLHttpRequest() to perform a new Ajax request, dom.document to access the global document object, or html.Div to to refer to the type of a <div> element.
+
+
+
+ Add the following to your sbt build definition:
+
+
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.2.0"
+
+
+ then enjoy the types available in org.scalajs.dom. scalajs-dom 2.2.0 is built and published for Scala.js 1.5+ with Scala 2.11, 2.12, 2.13, and 3.0+.
+
+
+ To begin with, scala-js-dom organizes the full-list of DOM APIs into a number of buckets:
+
+
+ -
+
dom.html: HTML element APIs
+ -
+
dom.svg: SVG element APIs
+ -
+
dom.idb: IndexedDB APIs
+ -
+
dom.css: CSS APIs
+ -
+
dom: Miscellanious, unclassified APIs
+
+
+ Most names have been shortened from names of the raw browser APIs, since the namespacing avoids collisions. By convention these types are imported qualified: e.g. as html.Canvas instead of directly as Canvas. There is also the dom.raw namespace which contains everything with their full, un-shortened name.
+
+
+ Here are some examples to get you started:
+
+
+
def main(div: html.Div) = {
+ val child = dom.document.createElement("div")
+ child.textContent = "Hi from Scala-js-dom"
+ div.appendChild(child)
+}
+
+
+
def main(pre: html.Pre) = {
+ pre.onmousemove = {
+ (e: dom.MouseEvent) =>
+ pre.textContent =
+ s"""e.clientX ${e.clientX}
+ |e.clientY ${e.clientY}
+ |e.pageX ${e.pageX}
+ |e.pageY ${e.pageY}
+ |e.screenX ${e.screenX}
+ |e.screenY ${e.screenY}
+ """.stripMargin
+ }
+}
+
+
+
def main(in: html.Input,
+ out: html.Div) = {
+ in.onkeyup = { (e: dom.Event) =>
+ out.textContent =
+ dom.window.btoa(in.value)
+ }
+}
+
+
+
def main(in: html.Input, box: html.Div) = {
+ val key = "my-key"
+
+ in.value =
+ dom.window.localStorage.getItem(key)
+
+ in.onkeyup = { (e: dom.Event) =>
+ dom.window.localStorage.setItem(
+ key, in.value
+ )
+ box.textContent =
+ "Saved! " + in.value
+ }
+}
+
+
+
def main(c: html.Canvas) = {
+ type Ctx2D =
+ dom.CanvasRenderingContext2D
+ val ctx = c.getContext("2d")
+ .asInstanceOf[Ctx2D]
+ val w = 300
+ c.width = w
+ c.height = w
+
+ ctx.strokeStyle = "red"
+ ctx.lineWidth = 3
+ ctx.beginPath()
+ ctx.moveTo(w/3, 0)
+ ctx.lineTo(w/3, w/3)
+ ctx.moveTo(w*2/3, 0)
+ ctx.lineTo(w*2/3, w/3)
+ ctx.moveTo(w, w/2)
+ ctx.arc(w/2, w/2, w/2, 0, 3.14)
+
+ ctx.stroke()
+}
+
+
+
def main(pre: html.Pre) = {
+ import scala.concurrent
+ .ExecutionContext
+ .Implicits
+ .global
+ import js.Thenable.Implicits._
+ val url =
+ "https://www.boredapi.com/api/activity"
+ val responseText = for {
+ response <- dom.fetch(url)
+ text <- response.text()
+ } yield {
+ text
+ }
+ for (text <- responseText)
+ pre.textContent = text
+}
+
+
+
def main(in: html.Input,
+ pre: html.Pre) = {
+ val echo = "wss://echo.websocket.org"
+ val socket = new dom.WebSocket(echo)
+ socket.onmessage = {
+ (e: dom.MessageEvent) =>
+ pre.textContent +=
+ e.data.toString
+ }
+ socket.onopen = { (e: dom.Event) =>
+ in.onkeyup = { (e: dom.Event) =>
+ socket.send(in.value)
+ }
+ }
+}
+
+
+
def main(div: html.Div) = {
+ val colors = Seq(
+ "red", "green", "blue"
+ )
+
+ val index =
+ util.Random.nextInt(colors.length)
+
+ div.style.color = colors(index)
+}
+
+
+ The goal of this project is to provide a thin-but-idiomatic-scala interface to modern browser APIs. In particular:
+
+ -
+ Deprecated properties/methods/types will not be present.
+ -
+ IE-only, Chrome-only, FF-only, and in general browser-specific attributes will typically not be present.
+ -
+ The name of a Scala type should map directly to the name of the corresponding Javascript type.
+ -
+ Any type which is a Javascript type (e.g. you can
instanceof in javascript) should be a Scala class; any other interface which isn't a Javascript type should be a trait.
+ -
+ Read-only members should be
def, and not-directly-instantiable classes should have private constructors.
+
+
+
+ The DOM API is always evolving, and scala-js-dom is a hodgepodge of auto-generated/scraped/hand-tweaked code full of rough edges. If you see something that you think can be improved, feel free to send a pull request. These could include:
+
+ -
+ Improved doc-comments; who doesn't love better docs?
+ -
+ Missing methods/properties/classes; send the PR adding it in including it together with a link to an authoritative source (e.g. MDN) and it should get merged.