Introduction to the DOM - Web APIs

Introduction to the DOM
=======================

 The **Document Object Model** (*DOM*) is the data representation of the objects
 that comprise the structure and content of a document on the web.
 This guide will introduce the DOM,
 look at how the DOM represents an HTML document in memory
 and how to use APIs to create web content and applications.

What is the DOM?
----------------

 The Document Object Model (DOM) is a programming interface for web documents.
 It represents the page so that programs can change the document structure, style, and content.
 The DOM represents the document as nodes and objects;
 that way, programming languages can interact with the page.

A web page is a document that can be either displayed in the browser window or as the HTML source. In both cases, it is the same document but the Document Object Model (DOM) representation allows it to be manipulated. As an object-oriented representation of the web page, it can be modified with a scripting language such as JavaScript.

For example, the DOM specifies that the `querySelectorAll` method in this code snippet must return a list of all the `<p>` elements in the document:

```js
const paragraphs = document.querySelectorAll("p");
// paragraphs[0] is the first <p> element
// paragraphs[1] is the second <p> element, etc.
alert(paragraphs[0].nodeName);
```

All of the properties, methods, and events available for manipulating and creating web pages are organized into objects. For example, the `document` object that represents the document itself, any `table` objects that implement the `HTMLTableElement` DOM interface for accessing HTML tables, and so forth, are all objects.

 The DOM is built using multiple APIs that work together.
 The core DOM defines the entities
 describing any document and the objects within it.
 This is expanded upon as needed by other APIs that add new features and capabilities to the DOM.
 For example, the HTML DOM API adds support for representing HTML documents to the core DOM,
 and the SVG API adds support for representing SVG documents.

DOM and JavaScript
------------------

The previous short example, like nearly all examples, is JavaScript. That is to say, it is *written* in JavaScript, but *uses* the DOM to access the document and its elements. The DOM is not a programming language, but without it, the JavaScript language wouldn't have any model or notion of web pages, HTML documents, SVG documents, and their component parts. The document as a whole, the head, tables within the document, table headers, text within the table cells, and all other elements in a document are parts of the document object model for that document. They can all be accessed and manipulated using the DOM and a scripting language like JavaScript.

 The DOM is not part of the JavaScript language,
 but is instead a Web API used to build websites.
 JavaScript can also be used in other contexts.
 For example, Node.js runs JavaScript programs on a computer,
 but provides a different set of APIs,
 and the DOM API is not a core part of the Node.js runtime.

 The DOM was designed to be independent of any particular programming language, making the structural representation of the document available from a single, consistent API.
 Even if most web developers will only use the DOM through JavaScript, implementations of the DOM can be built for any language, as this Python example demonstrates:

```python
# Python DOM example
import xml.dom.minidom as m
doc = m.parse(r"C:\Projects\Py\chap1.xml")
doc.nodeName # DOM property of document object
p_list = doc.getElementsByTagName("para")
```

For more information on what technologies are involved in writing JavaScript on the web, see JavaScript technologies overview.

Accessing the DOM
-----------------

 You don't have to do anything special to begin using the DOM.
 You use the API directly in JavaScript from within what is called a *script*, a program run by a browser.

When you create a script, whether inline in a `<script>` element or included in the web page, you can immediately begin using the API for the `document` or `window` objects to manipulate the document itself, or any of the various elements in the web page (the descendant elements of the document). Your DOM programming may be something as simple as the following example, which displays a message on the console by using the `console.log()` function:

```html
<body onload="console.log('Welcome to my home page!');">
  …
</body>
```

 As it is generally not recommended to mix the structure of the page (written in HTML)
 and manipulation of the DOM (written in JavaScript),
 the JavaScript parts will be grouped together here,
 and separated from the HTML.

 For example, the following function creates a new h1 element,
 adds text to that element,
 and then adds it to the tree for the document:

```html
<html lang="en">
  <head>
    <script>
 // run this function when the document is loaded
 window.onload = () => {
 // create a couple of elements in an otherwise empty HTML page
 const heading = document.createElement("h1");
 const headingText = document.createTextNode("Big Head!");
 heading.appendChild(headingText);
 document.body.appendChild(heading);
 };
 </script>
  </head>
  <body></body>
</html>
```

Fundamental data types
----------------------

This page tries to describe the various objects and types in simple terms. But there are a number of different data types being passed around the API that you should be aware of.

**Note:** Because the vast majority of code that uses the DOM revolves around manipulating HTML documents, it's common to refer to the nodes in the DOM as **elements**, although strictly speaking not every node is an element.

The following table briefly describes these data types.

| Data type (Interface) | Description |
| --- | --- |
| `Document` |
 When a member returns an object of type `document` (e.g., the
 `ownerDocument` property of an element returns the
 `document` to which it belongs), this object is the root
 `document` object itself. The
 DOM `document` Reference
 chapter describes the `document` object.
  |
| `Node` |
 Every object located within a document is a node of some kind. In an
 HTML document, an object can be an element node but also a text node or
 attribute node.
  |
| `Element` |
 The `element` type is based on `node`. It refers
 to an element or a node of type `element` returned by a
 member of the DOM API. Rather than saying, for example, that the
 `document.createElement()` method returns an
 object reference to a `node`, we just say that this method
 returns the `element` that has just been created in the DOM.
 `element` objects implement the DOM
 `Element` interface and also the more basic
 `Node` interface, both of which are included together in this
 reference. In an HTML document, elements are further enhanced by the
 HTML DOM API's `HTMLElement` interface as well as
 other interfaces describing capabilities of specific kinds of elements
 (for instance, `HTMLTableElement` for
 `<table>` elements).
  |
| `NodeList` |
 A `nodeList` is an array of elements, like the kind that is
 returned by the method
 `document.querySelectorAll()`. Items in a
 `nodeList` are accessed by index in either of two ways:
 * list.item(1)
* list[1]

These two are equivalent. In the first, `item()` is the
 single method on the `nodeList` object. The latter uses the
 typical array syntax to fetch the second item in the list.
  |
| `Attr` |
 When an `attribute` is returned by a member (e.g., by the
 `createAttribute()` method), it is an object reference that
 exposes a special (albeit small) interface for attributes. Attributes
 are nodes in the DOM just like elements are, though you may rarely use
 them as such.
  |
| `NamedNodeMap` |
 A `namedNodeMap` is like an array, but the items are accessed
 by name or index, though this latter case is merely a convenience for
 enumeration, as they are in no particular order in the list. A
 `namedNodeMap` has an `item()` method for this
 purpose, and you can also add and remove items from a
 `namedNodeMap`.
  |

There are also some common terminology considerations to keep in mind. It's common to refer to any `Attr` node as an `attribute`, for example, and to refer to an array of DOM nodes as a `nodeList`. You'll find these terms and others to be introduced and used throughout the documentation.

DOM interfaces
--------------

This guide is about the objects and the actual *things* you can use to manipulate the DOM hierarchy. There are many points where understanding how these work can be confusing. For example, the object representing the HTML `form` element gets its `name` property from the `HTMLFormElement` interface but its `className` property from the `HTMLElement` interface. In both cases, the property you want is in that form object.

But the relationship between objects and the interfaces that they implement in the DOM can be confusing, and so this section attempts to say a little something about the actual interfaces in the DOM specification and how they are made available.

### Interfaces and objects

Many objects implement several different interfaces. The table object, for example, implements a specialized `HTMLTableElement` interface, which includes such methods as `createCaption` and `insertRow`. But since it's also an HTML element, `table` implements the `Element` interface described in the DOM `Element` Reference chapter. And finally, since an HTML element is also, as far as the DOM is concerned, a node in the tree of nodes that make up the object model for an HTML or XML page, the table object also implements the more basic `Node` interface, from which `Element` derives.

When you get a reference to a `table` object, as in the following example, you routinely use all three of these interfaces interchangeably on the object, perhaps without knowing it.

```js
const table = document.getElementById("table");
const tableAttrs = table.attributes; // Node/Element interface
for (let i = 0; i < tableAttrs.length; i++) {
  // HTMLTableElement interface: border attribute
  if (tableAttrs[i].nodeName.toLowerCase() === "border") {
    table.border = "1";
  }
}
// HTMLTableElement interface: summary attribute
table.summary = "note: increased border";
```

### Core interfaces in the DOM

This section lists some of the most commonly-used interfaces in the DOM. The idea is not to describe what these APIs do here but to give you an idea of the sorts of methods and properties you will see very often as you use the DOM. These common APIs are used in the longer examples in the DOM Examples chapter at the end of this book.

The `document` and `window` objects are the objects whose interfaces you generally use most often in DOM programming. In simple terms, the `window` object represents something like the browser, and the `document` object is the root of the document itself. `Element` inherits from the generic `Node` interface, and together these two interfaces provide many of the methods and properties you use on individual elements. These elements may also have specific interfaces for dealing with the kind of data those elements hold, as in the `table` object example in the previous section.

The following is a brief list of common APIs in web and XML page scripting using the DOM.

* `document.querySelector()`
* `document.querySelectorAll()`
* `document.createElement()`
* `Element.innerHTML`
* `Element.setAttribute()`
* `Element.getAttribute()`
* `EventTarget.addEventListener()`
* `HTMLElement.style`
* `Node.appendChild()`
* `window.onload`
* `window.scrollTo()`
Examples
--------

### Setting text content

This example uses a `<div>` element containing a `<textarea>` and two `<button>` elements. When the user clicks the first button we set some text in the `<textarea>`. When the user clicks the second button we clear the text. We use:

* `Document.querySelector()` to access the `<textarea>` and the button
* `EventTarget.addEventListener()` to listen for button clicks
* `Node.textContent` to set and clear the text.

#### HTML

```html
<div class="container">
  <textarea class="story"></textarea>
  <button id="set-text" type="button">Set text content</button>
  <button id="clear-text" type="button">Clear text content</button>
</div>
```

#### CSS

```css
.container {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

button {
  width: 200px;
}
```

#### JavaScript

```js
const story = document.body.querySelector(".story");

const setText = document.body.querySelector("#set-text");
setText.addEventListener("click", () => {
  story.textContent = "It was a dark and stormy night...";
});

const clearText = document.body.querySelector("#clear-text");
clearText.addEventListener("click", () => {
  story.textContent = "";
});
```

#### Result

### Adding a child element

This example uses a `<div>` element containing a `<div>` and two `<button>` elements. When the user clicks the first button we create a new element and add it as a child of the `<div>`. When the user clicks the second button we remove the child element. We use:

* `Document.querySelector()` to access the `<div>` and the buttons
* `EventTarget.addEventListener()` to listen for button clicks
* `Document.createElement` to create the element
* `Node.appendChild()` to add the child
* `Node.removeChild()` to remove the child.

#### HTML

```html
<div class="container">
  <div class="parent">parent</div>
  <button id="add-child" type="button">Add a child</button>
  <button id="remove-child" type="button">Remove child</button>
</div>
```

#### CSS

```css
.container {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

button {
  width: 100px;
}

div.parent {
  border: 1px solid black;
  padding: 5px;
  width: 100px;
  height: 100px;
}

div.child {
  border: 1px solid red;
  margin: 10px;
  padding: 5px;
  width: 80px;
  height: 60px;
  box-sizing: border-box;
}
```

#### JavaScript

```js
const parent = document.body.querySelector(".parent");

const addChild = document.body.querySelector("#add-child");
addChild.addEventListener("click", () => {
  // Only add a child if we don't already have one
  // in addition to the text node "parent"
  if (parent.childNodes.length > 1) {
    return;
  }
  const child = document.createElement("div");
  child.classList.add("child");
  child.textContent = "child";
  parent.appendChild(child);
});

const removeChild = document.body.querySelector("#remove-child");
removeChild.addEventListener("click", () => {
  const child = document.body.querySelector(".child");
  parent.removeChild(child);
});
```

#### Result

Specifications
--------------

| Specification |
| --- |
| DOM Standard  |


How whitespace is handled by HTML, CSS, and in the DOM - Web APIs

How whitespace is handled by HTML, CSS, and in the DOM
======================================================

The presence of whitespace in the DOM can cause layout problems and make manipulation of the content tree difficult in unexpected ways, depending on where it is located. This article explores when difficulties can occur, and looks at what can be done to mitigate resulting problems.

What is whitespace?
-------------------

Whitespace is any string of text composed only of spaces, tabs or line breaks (to be precise, CRLF sequences, carriage returns or line feeds). These characters allow you to format your code in a way that will make it easily readable by yourself and other people. In fact, much of our source code is full of these whitespace characters, and we only tend to get rid of it in a production build step to reduce code download sizes.

### HTML largely ignores whitespace?

In the case of HTML, whitespace is largely ignored — whitespace in between words is treated as a single character, and whitespace at the start and end of elements and outside elements is ignored. Take the following minimal example:

```html
<!DOCTYPE html>

  <h1>      Hello      World!     </h1>
```

This source code contains a couple of line feeds after the `DOCTYPE` and a bunch of space characters before, after, and inside the `<h1>` element, but the browser doesn't seem to care at all and just shows the words "Hello World!" as if these characters didn't exist at all:

This is so that whitespace characters don't impact the layout of your page. Creating space around and inside elements is the job of CSS.

### What happens to whitespace?

They don't just disappear, however.

Any whitespace characters that are outside of HTML elements in the original document are represented in the DOM. This is needed internally so that the editor can preserve formatting of documents. This means that:

* There will be some text nodes that contain only whitespace, and
* Some text nodes will have whitespace at the beginning or end.

Take the following document, for example:

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>My Document</title>
  </head>
  <body>
    <h1>Header</h1>
    <p>Paragraph</p>
  </body>
</html>
```

The DOM tree for this looks like so:

![The DOM tree representing a simple HTML document](/en-US/docs/Web/API/Document_Object_Model/Whitespace/dom-string.png)

Conserving whitespace characters in the DOM is useful in many ways, but there are certain places where this makes certain layouts more difficult to implement, and causes problems for developers who want to iterate through nodes in the DOM. We'll look at these, and some solutions, later on.

### How does CSS process whitespace?

Most whitespace characters are ignored, not all of them are. In the earlier example one of the spaces between "Hello" and "World!" still exists when the page is rendered in a browser. There are rules in the browser engine that decide which whitespace characters are useful and which aren't — these are specified at least in part in CSS Text Module Level 3, and especially the parts about the CSS `white-space` property and whitespace processing details, but we also offer an easier explanation below.

#### Example

Let's take another example. To make it easier, we've added a comment that shows all spaces with ◦, all tabs with ⇥, and all line breaks with ⏎:

This example:

```html
<h1>   Hello
        <span> World!</span>   </h1>

<!--
<h1>◦◦◦Hello◦⏎
⇥⇥⇥⇥<span>◦World!</span>⇥◦◦</h1>
-->
```

is rendered in the browser like so:

#### Explanation

The `<h1>` element contains only inline elements. In fact it contains:

* A text node (consisting of some spaces, the word "Hello" and some tabs).
* An inline element (the `<span>`, which contains a space, and the word "World!").
* Another text node (consisting only of tabs and spaces).

Because of this, it establishes what is called an inline formatting context. This is one of the possible layout rendering contexts that browser engines work with.

Inside this context, whitespace character processing can be summarized as follows:

1. First, all spaces and tabs immediately before and after a line break are ignored so, if we take our example markup from before:

```html
<h1>◦◦◦Hello◦⏎
⇥⇥⇥⇥<span>◦World!</span>⇥◦◦</h1>
```

...and apply this first rule, we get:

```html
<h1>◦◦◦Hello⏎
<span>◦World!</span>⇥◦◦</h1>
```

2. Next, all tab characters are handled as space characters, so the example becomes:

```html
<h1>◦◦◦Hello⏎
<span>◦World!</span>◦◦◦</h1>
```

3. Next, line breaks are converted to spaces:

```html
<h1>◦◦◦Hello◦<span>◦World!</span>◦◦◦</h1>
```

4. After that, any space immediately following another space (even across two separate inline elements) is ignored, so we end up with:

```html
<h1>◦Hello◦<span>World!</span>◦</h1>
```

5. And finally, sequences of spaces at the beginning and end of an element are removed, so we finally get this:

```html
<h1>Hello◦<span>World!</span></h1>
```

This is why people visiting the web page will see the phrase "Hello World!" nicely written at the top of the page, rather than a weirdly indented "Hello" followed but an even more weirdly indented "World!" on the line below that.

**Note:** Firefox DevTools have supported highlighting text nodes since version 52, making it easier to see exactly what nodes whitespace characters are contained within. Pure whitespace nodes are marked with a "whitespace" label.

### Whitespace in block formatting contexts

Above we just looked at elements that contain inline elements, and inline formatting contexts. If an element contains at least one block element, then it instead establishes what is called a block formatting context.

Within this context, whitespace is treated very differently.

#### Example

Let's take a look at an example to explain how. We've marked the whitespace characters as before.

We have 3 text nodes that contain only whitespace, one before the first `<div>`, one between the 2 `<div>`s, and one after the second `<div>`.

```html
<body>
  <div>  Hello  </div>

   <div>  World!   </div>
</body>

<!--
<body>⏎
⇥<div>◦◦Hello◦◦</div>⏎
⏎
◦◦◦<div>◦◦World!◦◦</div>◦◦⏎
</body>
-->
```

This renders like so:

#### Explanation

We can summarize how the whitespace here is handled as follows (there may be some slight differences in exact behavior between browsers, but this basically works):

1. Because we're inside a block formatting context, everything must be a block, so our 3 text nodes also become blocks, just like the 2 `<div>`s. Blocks occupy the full width available and are stacked on top of each other, which means that, starting from the example above:

```html
<body>⏎
⇥<div>◦◦Hello◦◦</div>⏎
⏎
◦◦◦<div>◦◦World!◦◦</div>◦◦⏎
</body>
```

...we end up with a layout composed of this list of blocks:

```html
<block>⏎⇥</block>
<block>◦◦Hello◦◦</block>
<block>⏎◦◦◦</block>
<block>◦◦World!◦◦</block>
<block>◦◦⏎</block>
```

2. This is then simplified further by applying the processing rules for whitespace in inline formatting contexts to these blocks:

```html
<block></block>
<block>Hello</block>
<block></block>
<block>World!</block>
<block></block>
```

3. The 3 empty blocks we now have are not going to occupy any space in the final layout, because they don't contain anything, so we'll end up with only 2 blocks taking up space in the page. People viewing the web page see the words "Hello" and "World!" on 2 separate lines as you'd expect 2 `<div>`s to be laid out. The browser engine has essentially ignored all of the whitespace that was added in the source code.
Spaces in between inline and inline-block elements
--------------------------------------------------

Let's move on to look at a few issues that can arise due to whitespace, and what can be done about them. First of all, we'll look at what happens with spaces in between inline and inline-block elements. In fact, we saw this already in our very first example, when we described how whitespace is processed inside inline formatting contexts.

We said that there were rules to ignore most characters but that word-separating characters remain. When you're only dealing with block-level elements such as `<p>` that only contain inline elements such as `<em>`, `<strong>`, `<span>`, etc., you don't normally care about this because the extra whitespace that does make it to the layout is helpful to separate the words in the sentence.

It gets more interesting however when you start using `inline-block` elements. These elements behave like inline elements on the outside, and blocks on the inside, and are often used to display more complex pieces of UI than just text, side-by-side on the same line, for example navigation menu items.

Because they are blocks, many people expect that they will behave as such, but really they don't. If there is formatting whitespace between adjacent inline elements, this will result in space in the layout, just like the spaces between words in text.

### Example

Consider this example (again, we've included an HTML comment that shows the whitespace characters in the HTML):

```css
.people-list {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.people-list li {
  display: inline-block;
  width: 2em;
  height: 2em;
  background: #f06;
  border: 1px solid;
}
```

```html
<ul class="people-list">
  <li></li>

  <li></li>

  <li></li>

  <li></li>

  <li></li>
</ul>

<!--
<ul class="people-list">⏎
◦◦<li></li>⏎
⏎
◦◦<li></li>⏎
⏎
◦◦<li></li>⏎
⏎
◦◦<li></li>⏎
⏎
◦◦<li></li>⏎
</ul>
-->
```

This renders as follows:

You probably don't want the gaps in between the blocks — depending on the use case (is this a list of avatars, or horizontal nav buttons?), you probably want the element sides flush with each other, and to be able to control any spacing yourself.

The Firefox DevTools HTML Inspector will highlight text nodes, and also show you exactly what area the elements are taking up — useful if you are wondering what is causing the problem, and are maybe thinking you've got some extra margin in there or something!

![Example of displaying whitespaces between blocks in the Firefox DevTools HTML Inspector](/en-US/docs/Web/API/Document_Object_Model/Whitespace/whitespace-devtools.png)

### Solutions

There are a few ways of getting around this problem:

Use Flexbox to create the horizontal list of items instead of trying an `inline-block` solution. This handles everything for you, and is definitely the preferred solution:

```css
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: flex;
}
```

If you need to rely on `inline-block`, you could set the `font-size` of the list to 0. This only works if your blocks are not sized with ems (based on the `font-size`, so the block size would also end up being 0). rems would be a good choice here:

```css
ul {
  font-size: 0;
  /\* … \*/
}

li {
  display: inline-block;
  width: 2rem;
  height: 2rem;
  /\* … \*/
}
```

Or you could set negative margin on the list items:

```css
li {
  display: inline-block;
  width: 2rem;
  height: 2rem;
  margin-right: -0.25rem;
}
```

You can also solve this problem by putting your list items all on the same line in the source, which causes the whitespace nodes to not be created in the first place:

```html
<li></li><li></li><li></li><li></li><li></li>
```

DOM traversal and whitespace
----------------------------

When trying to do DOM manipulation in JavaScript, you can also encounter problems because of whitespace nodes. For example, if you have a reference to a parent node and want to affect its first element child using `Node.firstChild`, if there is a rogue whitespace node just after the opening parent tag you will not get the result you are expecting. The text node would be selected instead of the element you want to affect.

As another example, if you have a certain subset of elements that you want to do something to based on whether they are empty (have no child nodes) or not, you could check whether each element is empty using something like `Node.hasChildNodes()`, but again, if any target elements contain text nodes, you could end up with false results.

Whitespace helper functions
---------------------------

The JavaScript code below defines several functions that make it easier to deal with whitespace in the DOM:

```js
/\*\*
 \* Throughout, whitespace is defined as one of the characters
 \* "\t" TAB \u0009
 \* "\n" LF \u000A
 \* "\r" CR \u000D
 \* " " SPC \u0020
 \*
 \* This does not use JavaScript's "\s" because that includes non-breaking
 \* spaces (and also some other characters).
 \*/

/\*\*
 \* Determine whether a node's text content is entirely whitespace.
 \*
 \* @param nod A node implementing the |CharacterData| interface (i.e.,
 \* a |Text|, |Comment|, or |CDATASection| node
 \* @return True if all of the text content of |nod| is whitespace,
 \* otherwise false.
 \*/
function is\_all\_ws(nod) {
  return !/[^\t\n\r ]/.test(nod.textContent);
}

/\*\*
 \* Determine if a node should be ignored by the iterator functions.
 \*
 \* @param nod An object implementing the DOM1 |Node| interface.
 \* @return true if the node is:
 \* 1) A |Text| node that is all whitespace
 \* 2) A |Comment| node
 \* and otherwise false.
 \*/

function is\_ignorable(nod) {
  return (
    nod.nodeType === 8 || // A comment node
    (nod.nodeType === 3 && is\_all\_ws(nod))
  ); // a text node, all ws
}

/\*\*
 \* Version of |previousSibling| that skips nodes that are entirely
 \* whitespace or comments. (Normally |previousSibling| is a property
 \* of all DOM nodes that gives the sibling node, the node that is
 \* a child of the same parent, that occurs immediately before the
 \* reference node.)
 \*
 \* @param sib The reference node.
 \* @return Either:
 \* 1) The closest previous sibling to |sib| that is not
 \* ignorable according to |is\_ignorable|, or
 \* 2) null if no such node exists.
 \*/
function node\_before(sib) {
  while ((sib = sib.previousSibling)) {
    if (!is\_ignorable(sib)) {
      return sib;
    }
  }
  return null;
}

/\*\*
 \* Version of |nextSibling| that skips nodes that are entirely
 \* whitespace or comments.
 \*
 \* @param sib The reference node.
 \* @return Either:
 \* 1) The closest next sibling to |sib| that is not
 \* ignorable according to |is\_ignorable|, or
 \* 2) null if no such node exists.
 \*/
function node\_after(sib) {
  while ((sib = sib.nextSibling)) {
    if (!is\_ignorable(sib)) {
      return sib;
    }
  }
  return null;
}

/\*\*
 \* Version of |lastChild| that skips nodes that are entirely
 \* whitespace or comments. (Normally |lastChild| is a property
 \* of all DOM nodes that gives the last of the nodes contained
 \* directly in the reference node.)
 \*
 \* @param sib The reference node.
 \* @return Either:
 \* 1) The last child of |sib| that is not
 \* ignorable according to |is\_ignorable|, or
 \* 2) null if no such node exists.
 \*/
function last\_child(par) {
  let res = par.lastChild;
  while (res) {
    if (!is\_ignorable(res)) {
      return res;
    }
    res = res.previousSibling;
  }
  return null;
}

/\*\*
 \* Version of |firstChild| that skips nodes that are entirely
 \* whitespace and comments.
 \*
 \* @param sib The reference node.
 \* @return Either:
 \* 1) The first child of |sib| that is not
 \* ignorable according to |is\_ignorable|, or
 \* 2) null if no such node exists.
 \*/
function first\_child(par) {
  let res = par.firstChild;
  while (res) {
    if (!is\_ignorable(res)) {
      return res;
    }
    res = res.nextSibling;
  }
  return null;
}

/\*\*
 \* Version of |data| that doesn't include whitespace at the beginning
 \* and end and normalizes all whitespace to a single space. (Normally
 \* |data| is a property of text nodes that gives the text of the node.)
 \*
 \* @param txt The text node whose data should be returned
 \* @return A string giving the contents of the text node with
 \* whitespace collapsed.
 \*/
function data\_of(txt) {
  let data = txt.textContent;
  data = data.replace(/[\t\n\r ]+/g, " ");
  if (data[0] === " ") {
    data = data.substring(1, data.length);
  }
  if (data[data.length - 1] === " ") {
    data = data.substring(0, data.length - 1);
  }
  return data;
}
```

### Example

The following code demonstrates the use of the functions above. It iterates over the children of an element (whose children are all elements) to find the one whose text is `"This is the third paragraph"`, and then changes the class attribute and the contents of that paragraph.

```js
let cur = first\_child(document.getElementById("test"));
while (cur) {
  if (data\_of(cur.firstChild) === "This is the third paragraph.") {
    cur.className = "magic";
    cur.firstChild.textContent = "This is the magic paragraph.";
  }
  cur = node\_after(cur);
}
```


Examples of web and XML development using the DOM - Web APIs

Examples of web and XML development using the DOM
=================================================

This chapter provides some longer examples of web and XML development using the DOM. Wherever possible, the examples use common APIs, tricks, and patterns in JavaScript for manipulating the document object.

Example 1: height and width
---------------------------

The following example shows the use of the `height` and `width` properties alongside images of varying dimensions:

```html
<!doctype html>
<html lang="en">
  <head>
    <title>width/height example</title>
    <script>
 function init() {
 const arrImages = new Array(3);

 arrImages[0] = document.getElementById("image1");
 arrImages[1] = document.getElementById("image2");
 arrImages[2] = document.getElementById("image3");

 const objOutput = document.getElementById("output");
 let strHtml = "<ul>";

 for (let i = 0; i < arrImages.length; i++) {
 strHtml +=
 "<li>image" +
 (i + 1) +
 ": height=" +
 arrImages[i].height +
 ", width=" +
 arrImages[i].width +
 ", style.height=" +
 arrImages[i].style.height +
 ", style.width=" +
 arrImages[i].style.width +
 "<\/li>";
 }

 strHtml += "<\/ul>";

 objOutput.innerHTML = strHtml;
 }
 </script>
  </head>
  <body onload="init();">
    <p>
      Image 1: no height, width, or style
      <img id="image1" src="http://www.mozilla.org/images/mozilla-banner.gif" />
    </p>

    <p>
      Image 2: height="50", width="500", but no style
      <img
 id="image2"
 src="http://www.mozilla.org/images/mozilla-banner.gif"
 height="50"
 width="500" />
    </p>

    <p>
      Image 3: no height, width, but style="height: 50px; width: 500px;"
      <img
 id="image3"
 src="http://www.mozilla.org/images/mozilla-banner.gif"
 style="height: 50px; width: 500px;" />
    </p>

    <div id="output"></div>
  </body>
</html>
```

Example 2: Image Attributes
---------------------------

```html
<!doctype html>
<html lang="en">
  <head>
    <title>Modifying an image border</title>

    <script>
 function setBorderWidth(width) {
 document.getElementById("img1").style.borderWidth = width + "px";
 }
 </script>
  </head>

  <body>
    <p>
      <img
 id="img1"
 src="image1.gif"
 style="border: 5px solid green;"
 width="100"
 height="100"
 alt="border test" />
    </p>

    <form name="FormName">
      <input
 type="button"
 value="Make border 20px-wide"
 onclick="setBorderWidth(20);" />
      <input
 type="button"
 value="Make border 5px-wide"
 onclick="setBorderWidth(5);" />
    </form>
  </body>
</html>
```

Example 3: Manipulating Styles
------------------------------

In this simple example, some basic style properties of an HTML paragraph element are accessed using the style object on the element and that object's CSS style properties, which can be retrieved and set from the DOM. In this case, you are manipulating the individual styles directly. In the next example (see Example 4), you can use stylesheets and their rules to change styles for whole documents.

```html
<!doctype html>
<html lang="en">
  <head>
    <title>Changing color and font-size example</title>

    <script>
 function changeText() {
 const p = document.getElementById("pid");

 p.style.color = "blue";
 p.style.fontSize = "18pt";
 }
 </script>
  </head>
  <body>
    <p id="pid" onclick="window.location.href = 'http://www.cnn.com/';">
      linker
    </p>

    <form>
      <p><input value="rec" type="button" onclick="changeText();" /></p>
    </form>
  </body>
</html>
```

Example 4: Using Stylesheets
----------------------------

The `styleSheets` property on the `document` object returns a list of the stylesheets that have been loaded on that document. You can access these stylesheets and their rules individually using the stylesheet, style, and `CSSRule` objects, as demonstrated in this example, which prints out all of the style rule selectors to the console.

```js
const ss = document.styleSheets;

for (let i = 0; i < ss.length; i++) {
  for (let j = 0; j < ss[i].cssRules.length; j++) {
    dump(`${ss[i].cssRules[j].selectorText}\n`);
  }
}
```

For a document with a single stylesheet in which the following three rules are defined:

```css
body {
  background-color: darkblue;
}
p {
  font-family: Arial;
  font-size: 10pt;
  margin-left: 0.125in;
}
#lumpy {
  display: none;
}
```

This script outputs the following:
```

BODY
P
#LUMPY
```

Example 5: Event Propagation
----------------------------

This example demonstrates how events fire and are handled in the DOM in a very simple way. When the BODY of this HTML document loads, an event listener is registered with the top row of the TABLE. The event listener handles the event by executing the function stopEvent, which changes the value in the bottom cell of the table.

However, stopEvent also calls an event object method, `event.stopPropagation`, which keeps the event from bubbling any further up into the DOM. Note that the table itself has an `onclick` event handler that ought to display a message when the table is clicked. But the stopEvent method has stopped propagation, and so after the data in the table is updated, the event phase is effectively ended, and an alert box is displayed to confirm this.

```html
<!doctype html>
<html lang="en">
  <head>
    <title>Event Propagation</title>

    <style>
 #t-daddy {
 border: 1px solid red;
 }
 #c1 {
 background-color: pink;
 }
 </style>

    <script>
 function stopEvent(event) {
 const c2 = document.getElementById("c2");
 c2.textContent = "hello";

 // this ought to keep t-daddy from getting the click.
 event.stopPropagation();
 alert("event propagation halted.");
 }

 function load() {
 const elem = document.getElementById("tbl1");
 elem.addEventListener("click", stopEvent, false);
 }
 </script>
  </head>

  <body onload="load();">
    <table id="t-daddy" onclick="alert('hi');">
      <tr id="tbl1">
        <td id="c1">one</td>
      </tr>
      <tr>
        <td id="c2">two</td>
      </tr>
    </table>
  </body>
</html>
```

Example 6: getComputedStyle
---------------------------

This example demonstrates how the `window.getComputedStyle` method can be used to get the styles of an element that are not set using the `style` attribute or with JavaScript (e.g., `elt.style.backgroundColor="rgb(173 216 230)"`). These latter types of styles can be retrieved with the more direct `elt.style` property, whose properties are listed in the DOM CSS Properties List.

`getComputedStyle()` returns a `CSSStyleDeclaration` object, whose individual style properties can be referenced with this object's `getPropertyValue()` method, as the following example document shows.

```html
<!doctype html>
<html lang="en">
  <head>
    <title>getComputedStyle example</title>

    <script>
 function cStyles() {
 const RefDiv = document.getElementById("d1");
 const txtHeight = document.getElementById("t1");
 const h\_style = document.defaultView
 .getComputedStyle(RefDiv, null)
 .getPropertyValue("height");

 txtHeight.value = h\_style;

 const txtWidth = document.getElementById("t2");
 const w\_style = document.defaultView
 .getComputedStyle(RefDiv, null)
 .getPropertyValue("width");

 txtWidth.value = w\_style;

 const txtBackgroundColor = document.getElementById("t3");
 const b\_style = document.defaultView
 .getComputedStyle(RefDiv, null)
 .getPropertyValue("background-color");

 txtBackgroundColor.value = b\_style;
 }
 </script>

    <style>
 #d1 {
 margin-left: 10px;
 background-color: rgb(173 216 230);
 height: 20px;
 max-width: 20px;
 }
 </style>
  </head>

  <body>
    <div id="d1"> </div>

    <form action="">
      <p>
        <button type="button" onclick="cStyles();">getComputedStyle</button>
        height<input id="t1" type="text" value="1" /> max-width<input
 id="t2"
 type="text"
 value="2" />
        bg-color<input id="t3" type="text" value="3" />
      </p>
    </form>
  </body>
</html>
```

Example 7: Displaying Event Object Properties
---------------------------------------------

This example uses DOM methods to display all the properties of the `onload` `event` object and their values in a table. It also shows a useful technique of using a `for...in` loop to iterate over the properties of an object to get their values.

The properties of event objects differs greatly between browsers, the WHATWG DOM Standard lists the standard properties, however many browsers have extended these greatly.

Put the following code into a blank text file and load it into a variety of browsers, you'll be surprised at the different number and names of properties. You might also like to add some elements in the page and call this function from different event handlers.

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Show Event properties</title>

    <style>
 table {
 border-collapse: collapse;
 }
 thead {
 font-weight: bold;
 }
 td {
 padding: 2px 10px 2px 10px;
 }

 .odd {
 background-color: #efdfef;
 }
 .even {
 background-color: #ffffff;
 }
 </style>

    <script>
 function showEventProperties(e) {
 function addCell(row, text) {
 const cell = row.insertCell(-1);
 cell.appendChild(document.createTextNode(text));
 }

 const event = e || window.event;
 document.getElementById("eventType").innerHTML = event.type;

 const table = document.createElement("table");
 const thead = table.createTHead();
 let row = thead.insertRow(-1);
 const labelList = ["#", "Property", "Value"];
 const len = labelList.length;

 for (let i = 0; i < len; i++) {
 addCell(row, labelList[i]);
 }

 const tbody = document.createElement("tbody");
 table.appendChild(tbody);

 for (const p in event) {
 row = tbody.insertRow(-1);
 row.className = row.rowIndex % 2 ? "odd" : "even";
 addCell(row, row.rowIndex);
 addCell(row, p);
 addCell(row, event[p]);
 }

 document.body.appendChild(table);
 }

 window.onload = (event) => {
 showEventProperties(event);
 };
 </script>
  </head>

  <body>
    <h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
  </body>
</html>
```

Example 8: Using the DOM Table Interface
----------------------------------------

The DOM `HTMLTableElement` interface provides some convenience methods for creating and manipulating tables. Two frequently used methods are `HTMLTableElement.insertRow` and `HTMLTableRowElement.insertCell`.

To add a row and some cells to an existing table:

```html
<table id="table0">
  <tr>
    <td>Row 0 Cell 0</td>
    <td>Row 0 Cell 1</td>
  </tr>
</table>

<script>
 const table = document.getElementById("table0");
 const row = table.insertRow(-1);
 let cell;
 let text;

 for (let i = 0; i < 2; i++) {
 cell = row.insertCell(-1);
 text = "Row " + row.rowIndex + " Cell " + i;
 cell.appendChild(document.createTextNode(text));
 }
</script>
```

### Notes

* A table's `innerHTML` property should never be used to modify a table, although you can use it to write an entire table or the content of a cell.
* If DOM Core methods `document.createElement` and `Node.appendChild` are used to create rows and cells, IE requires that they are appended to a `<tbody>` element, whereas other browsers will allow appending to a `<table>` element (the rows will be added to the last `<tbody>` element).
* There are a number of other convenience methods belonging to the `HTMLTableElement` interface that can be used for creating and modifying tables.


Worker: messageerror event - Web APIs

Worker: messageerror event
==========================

The `messageerror` event is fired on a `Worker` object when it receives a message that can't be deserialized.

This event is not cancellable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("messageerror", (event) => {});

onmessageerror = (event) => {};
```

Event type
----------

A `MessageEvent`. Inherits from `Event`.

Event

MessageEventEvent properties
----------------

*This interface also inherits properties from its parent, `Event`.*

`MessageEvent.data` Read only

The data sent by the message emitter.

`MessageEvent.origin` Read only

A string representing the origin of the message emitter.

`MessageEvent.lastEventId` Read only

A string representing a unique ID for the event.

`MessageEvent.source` Read only

A `MessageEventSource` (which can be a WindowProxy, `MessagePort`, or `ServiceWorker` object) representing the message emitter.

`MessageEvent.ports` Read only

An array of `MessagePort` objects representing the ports associated with the channel the message is being sent through (where appropriate, e.g. in channel messaging or when sending a message to a shared worker).

Examples
--------

Create a worker, and listen for `message` and `messageerror` events using `addEventListener()`:

```js
// main.js

const worker = new Worker("static/scripts/worker.js");

worker.addEventListener("message", (event) => {
  console.error(`Received message from worker: ${event}`);
});

worker.addEventListener("messageerror", (event) => {
  console.error(`Error receiving message from worker: ${event}`);
});
```

The same, but using the `onmessageerror` event handler property:

```js
// main.js

const worker = new Worker("static/scripts/worker.js");

worker.onmessage = (event) => {
  console.error(`Received message from worker: ${event}`);
};

worker.onmessageerror = (event) => {
  console.error(`Error receiving message from worker: ${event}`);
};
```

Specifications
--------------

| Specification |
| --- |
| HTML Standard # event-messageerror |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Worker.postMessage()`
* Related events: `message`


Worker: Worker() constructor - Web APIs

Worker: Worker() constructor
============================

The **`Worker()`** constructor creates a `Worker` object that executes the script at the specified URL. This script must obey the same-origin policy.

**Note:** that there is a disagreement among browser manufacturers about whether a data URL is of the same origin or not. Though Firefox 10 and later accept data URLs, that's not the case in all other browsers.

Syntax
------

```js
new Worker(aURL)
new Worker(aURL, options)
```

### Parameters

`aURL`

A string representing the URL of the script the worker will execute. It must obey the same-origin policy.

`options` Optional

An object containing option properties that can be set when creating the object instance. Available properties are as follows:

`type`

A string specifying the type of worker to create. The value can be `classic` or `module`. If not specified, the default used is `classic`.

`credentials`

A string specifying the type of credentials to use for the worker. The value can be `omit`, `same-origin`, or *`include`. If not specified, or if type is `classic`, the default used is `omit` (no credentials required).*

`name`

A string specifying an identifying name for the `DedicatedWorkerGlobalScope` representing the scope of the worker, which is mainly useful for debugging purposes.

### Exceptions

`SecurityError` `DOMException`

Thrown if the document is not allowed to start workers, e.g. if the URL has an invalid syntax or if the same-origin policy is violated.

`NetworkError` `DOMException`

 Thrown if the MIME type of the worker script is incorrect. It *should* always be `text/javascript`
 (for historical reasons other JavaScript MIME types may be accepted).

`SyntaxError` `DOMException`

Thrown if *aURL* cannot be parsed.

Examples
--------

The following code snippet shows creation of a `Worker` object using the `Worker()` constructor and subsequent usage of the object:

```js
const myWorker = new Worker("worker.js");

first.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};
```

For a full example, see our Basic dedicated worker example (run dedicated worker).

Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-worker-dev |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

The `Worker` interface it belongs to.


Worker: error event - Web APIs

Worker: error event
===================

The **`error`** event of the `Worker` interface fires when an error occurs in the worker.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("error", (event) => {});

onerror = (event) => {};
```

Event type
----------

A generic `Event`.

Example
-------

The following code snippet creates a `Worker` object using the `Worker()` constructor and sets up an `onerror` handler on the resulting object:

```js
const myWorker = new Worker("worker.js");

myWorker.onerror = (event) => {
  console.log("There is an error with your worker!");
};
```

Specifications
--------------

| Specification |
| --- |
| HTML Standard # handler-abstractworker-onerror |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Worker: postMessage() method - Web APIs

Worker: postMessage() method
============================

The **`postMessage()`** method of the `Worker` interface sends a message to the worker. The first parameter is the data to send to the worker. The data may be any JavaScript object that can be handled by the structured clone algorithm.

The `Worker` `postMessage()` method delegates to the `MessagePort` `postMessage()` method, which adds a task on the event loop corresponding to the receiving `MessagePort`.

The `Worker` can send back information to the thread that spawned it using the `DedicatedWorkerGlobalScope.postMessage` method.

Syntax
------

```js
postMessage(message)
postMessage(message, options)
postMessage(message, transfer)
```

### Parameters

`message`

The object to deliver to the worker; this will be in the `data` field in the event delivered to the `DedicatedWorkerGlobalScope.message_event` event. This may be any value or JavaScript object handled by the structured clone algorithm, which includes cyclical references.

If the `message` parameter is *not* provided, a `SyntaxError` will be thrown by the parser. If the data to be passed to the worker is unimportant, `null` or `undefined` can be passed explicitly.

`options` Optional

An optional object containing a `transfer` field with an array of transferable objects to transfer ownership of. If the ownership of an object is transferred, it becomes unusable in the context it was sent from, and becomes available only to the worker it was sent to.

`transfer` Optional

An optional array of transferable objects to transfer ownership of. If the ownership of an object is transferred, it becomes unusable in the context it was sent from and becomes available only to the worker it was sent to.

Transferable objects are instances of classes like `ArrayBuffer`, `MessagePort` or `ImageBitmap` objects that can be transferred. `null` is not an acceptable value for `transfer`.

### Return value

None (`undefined`).

Examples
--------

The following code snippet shows the creation of a `Worker` object using the `Worker()` constructor. When either of two form inputs (`first` and `second`) have their values changed, `change` events invoke `postMessage()` to send the value of both inputs to the current worker.

```js
const myWorker = new Worker("worker.js");

first.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

second.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};
```

For a full example, see our simple worker example (run example).

**Note:** `postMessage()` can only send a single object at once. As seen above, if you want to pass multiple values you can send an array.

### Transfer Example

This minimum example has `main` create an `ArrayBuffer` and transfer it to `myWorker`, then has `myWorker` transfer it back to `main`, with the size logged at each step.

#### main.js code

```js
// create worker
const myWorker = new Worker("myWorker.js");

// listen for myWorker to transfer the buffer back to main
myWorker.addEventListener("message", function handleMessageFromWorker(msg) {
  console.log("message from worker received in main:", msg);

  const bufTransferredBackFromWorker = msg.data;

  console.log(
    "buf.byteLength in main AFTER transfer back from worker:",
    bufTransferredBackFromWorker.byteLength,
  );
});

// create the buffer
const myBuf = new ArrayBuffer(8);

console.log(
  "buf.byteLength in main BEFORE transfer to worker:",
  myBuf.byteLength,
);

// send myBuf to myWorker and transfer the underlying ArrayBuffer
myWorker.postMessage(myBuf, [myBuf]);

console.log(
  "buf.byteLength in main AFTER transfer to worker:",
  myBuf.byteLength,
);
```

#### myWorker.js code

```js
// listen for main to transfer the buffer to myWorker
self.onmessage = function handleMessageFromMain(msg) {
  console.log("message from main received in worker:", msg);

  const bufTransferredFromMain = msg.data;

  console.log(
    "buf.byteLength in worker BEFORE transfer back to main:",
    bufTransferredFromMain.byteLength,
  );

  // send buf back to main and transfer the underlying ArrayBuffer
  self.postMessage(bufTransferredFromMain, [bufTransferredFromMain]);

  console.log(
    "buf.byteLength in worker AFTER transfer back to main:",
    bufTransferredFromMain.byteLength,
  );
};
```

#### Output logged

```bash
buf.byteLength in main BEFORE transfer to worker:        8                     main.js:19
buf.byteLength in main AFTER transfer to worker:         0                     main.js:27

message from main received in worker:                    MessageEvent { ... }  myWorker.js:3
buf.byteLength in worker BEFORE transfer back to main:   8                     myWorker.js:7
buf.byteLength in worker AFTER transfer back to main:    0                     myWorker.js:15

message from worker received in main:                    MessageEvent { ... }  main.js:6
buf.byteLength in main AFTER transfer back from worker:  8                     main.js:10
```

`byteLength` goes to 0 after the `ArrayBuffer` is transferred. For a more sophisticated full working example of `ArrayBuffer` transfer, see this Firefox demo add-on: GitHub :: ChromeWorker - demo-transfer-arraybuffer

Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-worker-postmessage-dev |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `Worker` interface it belongs to.


Worker: message event - Web APIs

Worker: message event
=====================

The `message` event is fired on a `Worker` object when the worker's parent receives a message from its worker (i.e. when the worker sends a message using `DedicatedWorkerGlobalScope.postMessage()`).

This event is not cancellable and does not bubble.

Syntax
------

Use the event name in methods like `addEventListener()`, or set an event handler property.

```js
addEventListener("message", (event) => {});

onmessage = (event) => {};
```

Event type
----------

A `MessageEvent`. Inherits from `Event`.

Event

MessageEventEvent properties
----------------

*This interface also inherits properties from its parent, `Event`.*

`MessageEvent.data` Read only

The data sent by the message emitter.

`MessageEvent.origin` Read only

A string representing the origin of the message emitter.

`MessageEvent.lastEventId` Read only

A string representing a unique ID for the event.

`MessageEvent.source` Read only

A `MessageEventSource` (which can be a WindowProxy, `MessagePort`, or `ServiceWorker` object) representing the message emitter.

`MessageEvent.ports` Read only

An array of `MessagePort` objects representing the ports associated with the channel the message is being sent through (where appropriate, e.g. in channel messaging or when sending a message to a shared worker).

Examples
--------

This code creates a new worker and listens to messages from it using `addEventListener()`:

```js
const worker = new Worker("static/scripts/worker.js");

worker.addEventListener("message", (event) => {
  console.log(`Received message from worker: ${event.data}`);
});
```

Alternatively, it could listen using the `onmessage` event handler property:

```js
const worker = new Worker("static/scripts/worker.js");

worker.onmessage = (event) => {
  console.log(`Received message from worker: ${event.data}`);
};
```

The worker posts messages using `self.postMessage()`:

```js
// static/scripts/worker.js

self.postMessage("I'm alive!");
```

Specifications
--------------

| Specification |
| --- |
| HTML Standard # event-message |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Related events: `messageerror`.
* `DedicatedWorkerGlobalScope.postMessage()`.


Worker: terminate() method - Web APIs

Worker: terminate() method
==========================

The **`terminate()`** method of the `Worker` interface immediately terminates the `Worker`. This does not offer the worker an opportunity to finish its operations; it is stopped at once.

Syntax
------

```js
terminate()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

The following code snippet shows creation of a `Worker` object using the `Worker()` constructor, which is then immediately terminated.

```js
const myWorker = new Worker("worker.js");

myWorker.terminate();
```

**Note:** DedicatedWorkers and SharedWorkers can also be stopped from the `Worker` instance using the `DedicatedWorkerGlobalScope.close()` or `SharedWorkerGlobalScope.close()` methods.

Specifications
--------------

| Specification |
| --- |
| HTML Standard # dom-worker-terminate-dev |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Worker` interface
* `DedicatedWorkerGlobalScope.close()`
* `SharedWorkerGlobalScope.close()`


BluetoothRemoteGATTServer: disconnect() method - Web APIs

BluetoothRemoteGATTServer: disconnect() method
==============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`BluetoothRemoteGATTServer.disconnect()`** method causes
 the script execution environment to disconnect from `this.device`.

Syntax
------

```js
disconnect()
```

### Parameters

None.

### Return value

None (`undefined`).

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-disconnect |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BluetoothRemoteGATTServer: connect() method - Web APIs

BluetoothRemoteGATTServer: connect() method
===========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The
 **`BluetoothRemoteGATTServer.connect()`** method causes the
 script execution environment to connect to `this.device`.

Syntax
------

```js
connect()
```

### Parameters

None.

### Return value

A `Promise` that resolves to a `BluetoothRemoteGATTServer`.

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-connect |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BluetoothRemoteGATTServer: device property - Web APIs

BluetoothRemoteGATTServer: device property
==========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`BluetoothRemoteGATTServer.device`** read-only property
 returns a reference to the `BluetoothDevice` running the server.

Value
-----

A reference to the `BluetoothDevice`.

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-device |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BluetoothRemoteGATTServer: getPrimaryServices() method - Web APIs

BluetoothRemoteGATTServer: getPrimaryServices() method
======================================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **BluetoothRemoteGATTServer.getPrimaryServices()** method returns a
 promise to a list of primary `BluetoothRemoteGATTService` objects offered by the
 Bluetooth device for a specified `BluetoothServiceUUID`.

Syntax
------

```js
getPrimaryServices(bluetoothServiceUUID)
```

### Parameters

`bluetoothServiceUUID`

A Bluetooth service universally unique identifier for a specified device.

### Return value

 A `Promise` that resolves to a list of `BluetoothRemoteGATTService`
 objects.

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-getprimaryservices |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BluetoothRemoteGATTServer: getPrimaryService() method - Web APIs

BluetoothRemoteGATTServer: getPrimaryService() method
=====================================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`BluetoothRemoteGATTServer.getPrimaryService()`** method
 returns a promise to the primary `BluetoothRemoteGATTService` offered by the
 Bluetooth device for a specified bluetooth service UUID.

Syntax
------

```js
getPrimaryService(bluetoothServiceUUID)
```

### Parameters

`bluetoothServiceUUID`

A Bluetooth service universally unique identifier for a specified device, that is either a 128-bit UUID, a 16-bit or 32-bit UUID alias, or a string from the list of GATT assigned services keys.

### Return value

A `Promise` that resolves to a `BluetoothRemoteGATTService` object.

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-getprimaryservice |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BluetoothRemoteGATTServer: connected property - Web APIs

BluetoothRemoteGATTServer: connected property
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`BluetoothRemoteGATTServer.connected`** read-only
 property returns a boolean value that returns true while this script execution
 environment is connected to `this.device`. It can be false while the user
 agent is physically connected.

Value
-----

A `boolean`.

Specifications
--------------

| Specification |
| --- |
| Web Bluetooth # dom-bluetoothremotegattserver-connected |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Comment: Comment() constructor - Web APIs

Comment: Comment() constructor
==============================

 The **`Comment()`** constructor returns a newly created
 `Comment` object with the optional string given in
 parameter as its textual content.

Syntax
------

```js
new Comment()
new Comment(aString)
```

### Parameters

* `aString` Optional
### Return value

A new `Comment` containing `aString`, or the empty string if no parameter was given.

Example
-------

```js
let comment = new Comment("Test");
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-comment-comment① |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The DOM interfaces index
* `Document.createComment()` is an outdated alternative to this constructor.


WebGLShaderPrecisionFormat: precision property - Web APIs

WebGLShaderPrecisionFormat: precision property
==============================================

The read-only **`WebGLShaderPrecisionFormat.precision`** property returns the number of bits of precision that can be represented.

For integer formats this value is always 0.

Examples
--------

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

gl.getShaderPrecisionFormat(gl.VERTEX\_SHADER, gl.MEDIUM\_FLOAT).precision; // 23
gl.getShaderPrecisionFormat(gl.FRAGMENT\_SHADER, gl.LOW\_INT).precision; // 0
```

Specifications
--------------

| Specification |
| --- |
| WebGL Specification # DOM-WebGLShaderPrecisionFormat-precision |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `WebGLShaderPrecisionFormat`
* `WebGLRenderingContext.getShaderPrecisionFormat()`


WebGLShaderPrecisionFormat: rangeMin property - Web APIs

WebGLShaderPrecisionFormat: rangeMin property
=============================================

The read-only **`WebGLShaderPrecisionFormat.rangeMin`** property returns the base 2 log of the absolute value of the minimum value that can be represented.

Examples
--------

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

gl.getShaderPrecisionFormat(gl.VERTEX\_SHADER, gl.MEDIUM\_FLOAT).rangeMin; // 127
gl.getShaderPrecisionFormat(gl.FRAGMENT\_SHADER, gl.LOW\_INT).rangeMin; // 24
```

Specifications
--------------

| Specification |
| --- |
| WebGL Specification # DOM-WebGLShaderPrecisionFormat-rangeMin |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `WebGLShaderPrecisionFormat`
* `WebGLRenderingContext.getShaderPrecisionFormat()`


WebGLShaderPrecisionFormat: rangeMax property - Web APIs

WebGLShaderPrecisionFormat: rangeMax property
=============================================

The read-only **`WebGLShaderPrecisionFormat.rangeMax`** property returns the base 2 log of the absolute value of the maximum value that can be represented.

Examples
--------

```js
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl");

gl.getShaderPrecisionFormat(gl.VERTEX\_SHADER, gl.MEDIUM\_FLOAT).rangeMax; // 127
gl.getShaderPrecisionFormat(gl.FRAGMENT\_SHADER, gl.LOW\_INT).rangeMax; // 24
```

Specifications
--------------

| Specification |
| --- |
| WebGL Specification # DOM-WebGLShaderPrecisionFormat-rangeMax |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `WebGLShaderPrecisionFormat`
* `WebGLRenderingContext.getShaderPrecisionFormat()`


NodeIterator: pointerBeforeReferenceNode property - Web APIs

NodeIterator: pointerBeforeReferenceNode property
=================================================

 The **`NodeIterator.pointerBeforeReferenceNode`** read-only
 property returns a boolean flag that indicates whether the
 `NodeFilter` is anchored before (if this value is `true`) or
 after (if this value is `false`) the anchor node indicated by the
 `NodeIterator.referenceNode` property.

Value
-----

A boolean.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
flag = nodeIterator.pointerBeforeReferenceNode;
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-pointerbeforereferencenode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`


NodeIterator: root property - Web APIs

NodeIterator: root property
===========================

 The **`NodeIterator.root`** read-only property represents the
 `Node` that is the root of what the `NodeIterator`
 traverses.

Value
-----

A `Node`.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
root = nodeIterator.root; // document.body in this case
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-root |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`.


NodeIterator: detach() method - Web APIs

NodeIterator: detach() method
=============================

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

 The **`NodeIterator.detach()`** method is a no-op, kept for
 backward compatibility only.

 Originally, it detached the `NodeIterator` from the set over which it
 iterates, releasing any resources used by the set and setting the iterator's state to
 `INVALID`. Once this method had been called, calls to other methods on
 `NodeIterator` would raise the `INVALID_STATE_ERR` exception.

Syntax
------

```js
detach()
```

### Parameters

None.

### Return value

None (`undefined`).

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
nodeIterator.detach(); // detaches the iterator

nodeIterator.nextNode(); // throws an INVALID\_STATE\_ERR exception
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-detach |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`.


NodeIterator: nextNode() method - Web APIs

NodeIterator: nextNode() method
===============================

 The **`NodeIterator.nextNode()`** method returns the next node
 in the set represented by the `NodeIterator` and advances the position of
 the iterator within the set. The first call to `nextNode()` returns the
 first node in the set.

This method returns `null` when there are no nodes left in the set.

 In old browsers, as specified in old versions of the specifications, the method may
 throws the `INVALID_STATE_ERR` `DOMException` if this method
 is called after the `NodeIterator.detach()`method. Recent browsers never
 throw.

Syntax
------

```js
nextNode()
```

### Parameters

None.

### Return value

A `Node` representing the node after the current node in the set represented by this `NodeIterator`, or `null` if the current node is the last node in the set.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
currentNode = nodeIterator.nextNode(); // returns the next node
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-nextnode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`.


NodeIterator: whatToShow property - Web APIs

NodeIterator: whatToShow property
=================================

 The **`NodeIterator.whatToShow`** read-only property represents
 an `unsigned integer` representing a bitmask signifying what types of nodes
 should be returned by the `NodeIterator`.

Value
-----

An `unsigned integer`.

The values that can be combined to form the bitmask are:

| Constant | Numerical value | Description |
| --- | --- | --- |
| `NodeFilter.SHOW_ALL` | `4294967295` (that is the max value of `unsigned long`) | Shows all nodes. |
| `NodeFilter.SHOW_ATTRIBUTE`
Deprecated
 | `2` |
 Shows attribute `Attr` nodes. This is meaningful
 only when creating a `NodeIterator` or
 `TreeWalker` with an
 `Attr` node as its root; in this case, it means
 that the attribute node will appear in the first position of the
 iteration or traversal. Since attributes are never children of other
 nodes, they do not appear when traversing over the document tree.
  |
| `NodeFilter.SHOW_CDATA_SECTION`
Deprecated
 | `8` | Shows `CDATASection` nodes. |
| `NodeFilter.SHOW_COMMENT` | `128` | Shows `Comment` nodes. |
| `NodeFilter.SHOW_DOCUMENT` | `256` | Shows `Document` nodes. |
| `NodeFilter.SHOW_DOCUMENT_FRAGMENT` | `1024` | Shows `DocumentFragment` nodes. |
| `NodeFilter.SHOW_DOCUMENT_TYPE` | `512` | Shows `DocumentType` nodes. |
| `NodeFilter.SHOW_ELEMENT` | `1` | Shows `Element` nodes. |
| `NodeFilter.SHOW_ENTITY`
Deprecated
 | `32` | Legacy, no more used. |
| `NodeFilter.SHOW_ENTITY_REFERENCE`

Deprecated
 | `16` | Legacy, no more used. |
| `NodeFilter.SHOW_NOTATION`
Deprecated
 | `2048` | Legacy, no more used. |
| `NodeFilter.SHOW_PROCESSING_INSTRUCTION` | `64` | Shows `ProcessingInstruction` nodes. |
| `NodeFilter.SHOW_TEXT` | `4` | Shows `Text` nodes. |

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT | NodeFilter.SHOW\_COMMENT | NodeFilter.SHOW\_TEXT,
  { acceptNode: (node) => NodeFilter.FILTER\_ACCEPT },
);
if (
  nodeIterator.whatToShow & NodeFilter.SHOW\_ALL ||
  nodeIterator.whatToShow & NodeFilter.SHOW\_COMMENT
) {
  // nodeIterator will show comments
}
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-whattoshow |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface this property belongs to: `NodeIterator`.


NodeIterator: previousNode() method - Web APIs

NodeIterator: previousNode() method
===================================

 The **`NodeIterator.previousNode()`** method returns the
 previous node in the set represented by the `NodeIterator` and moves the
 position of the iterator backwards within the set.

 This method returns `null` when the current node is the first node in the
 set.

 In old browsers, as specified in old versions of the specifications, the method may
 throws the `INVALID_STATE_ERR` `DOMException` if this method
 is called after the `NodeIterator.detach()`method. Recent browsers never
 throw.

Syntax
------

```js
previousNode()
```

### Parameters

None.

### Return value

A `Node` representing the node before the current node in the set represented by this `NodeIterator`, or `null` if the current node is the first node in the set.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
currentNode = nodeIterator.nextNode(); // returns the next node
previousNode = nodeIterator.previousNode(); // same result, since we backtracked to the previous node
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-previousnode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`.


NodeIterator: referenceNode property - Web APIs

NodeIterator: referenceNode property
====================================

 The **`NodeIterator.referenceNode`** read-only property returns the
 `Node` to which the iterator is anchored; as new nodes are inserted, the
 iterator remains anchored to the reference node as specified by this property.

Value
-----

A `Node`.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
node = nodeIterator.referenceNode;
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-referencenode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface it belongs to: `NodeIterator`


NodeIterator: filter property - Web APIs

NodeIterator: filter property
=============================

 The **`NodeIterator.filter`** read-only property returns a
 `NodeFilter` object, that is an object which implements an
 `acceptNode(node)` method, used to screen nodes.

 When creating the `NodeIterator`, the filter object is passed in as the
 third parameter, and the object method `acceptNode(node)` is
 called on every single node to determine whether or not to accept it. This function
 should return the constant `NodeFilter.FILTER_ACCEPT` for cases when the
 node should be accepted and `NodeFilter.FILTER_REJECT` for cases when the
 node should be rejected.

Value
-----

A `NodeFilter` object.

Examples
--------

```js
const nodeIterator = document.createNodeIterator(
  document.body,
  NodeFilter.SHOW\_ELEMENT,
  {
    acceptNode(node) {
      return NodeFilter.FILTER\_ACCEPT;
    },
  },
);
nodeFilter = nodeIterator.filter;
```

Specifications
--------------

| Specification |
| --- |
| DOM Standard # dom-nodeiterator-filter |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The interface this property belongs to: `NodeIterator`.


Crypto: randomUUID() method - Web APIs

Crypto: randomUUID() method
===========================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The **`randomUUID()`** method of the `Crypto` interface is used to generate a v4 UUID using a cryptographically secure random number generator.

Syntax
------

```js
randomUUID()
```

### Parameters

None.

### Return value

A string containing a randomly generated, 36 character long v4 UUID.

Examples
--------

The method is accessed through the global `crypto` property.

```js
/\* Assuming that self.crypto.randomUUID() is available \*/

let uuid = self.crypto.randomUUID();
console.log(uuid); // for example "36b8f84d-df4e-4d49-b662-bcde71a8764f"
```

Specifications
--------------

| Specification |
| --- |
| Web Cryptography API # Crypto-method-randomUUID |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Web Crypto API`
* `crypto` to get a `Crypto` object.
* `Crypto.getRandomValues`, a source for arbitrary amounts of secure random bytes.


Crypto: getRandomValues() method - Web APIs

Crypto: getRandomValues() method
================================

 The **`Crypto.getRandomValues()`** method lets you get cryptographically strong random values.
 The array given as the parameter is filled with random numbers (random in its cryptographic meaning).

 To guarantee enough performance, implementations are not using a truly random number generator, but they are using a pseudo-random number generator *seeded* with a value with enough entropy.
 The pseudo-random number generator algorithm (PRNG) may vary across user agents, but is suitable for cryptographic purposes.

`getRandomValues()` is the only member of the `Crypto` interface which can be used from an insecure context.

Syntax
------

```js
getRandomValues(typedArray)
```

### Parameters

`typedArray`

 An integer-based `TypedArray`, that is one of: `Int8Array`, `Uint8Array`,
 `Uint8ClampedArray`, `Int16Array`, `Uint16Array`,
 `Int32Array`, `Uint32Array`, `BigInt64Array`,
 `BigUint64Array` (but **not** `Float32Array` nor `Float64Array`).
 All elements in the array will be overwritten with random numbers.

### Return value

 The same array passed as `typedArray` but with its contents replaced with the newly generated random numbers.
 Note that `typedArray` is modified in-place, and no copy is made.

### Exceptions

`QuotaExceededError` `DOMException`

Thrown if the `byteLength` of `typedArray` exceeds 65,536.

Usage notes
-----------

 Don't use `getRandomValues()` to generate encryption keys.
 Instead, use the `generateKey()` method.
 There are a few reasons for this; for example, `getRandomValues()` is not guaranteed to be running in a secure context.

 There is no minimum degree of entropy mandated by the Web Cryptography specification.
 User agents are instead urged to provide the best entropy they can when generating random numbers,
 using a well-defined, efficient pseudorandom number generator built into the user agent itself,
 but seeded with values taken from an external source of pseudorandom numbers, such as a platform-specific random number function,
 the Unix `/dev/urandom` device, or other source of random or pseudorandom data.

Examples
--------

```js
const array = new Uint32Array(10);
self.crypto.getRandomValues(array);

console.log("Your lucky numbers:");
for (const num of array) {
  console.log(num);
}
```

Specifications
--------------

| Specification |
| --- |
| Web Cryptography API # Crypto-method-getRandomValues |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Crypto API
* `crypto` to get a `Crypto` object.
* `Math.random`, a non-cryptographic source of random numbers.


Crypto: subtle property - Web APIs

Crypto: subtle property
=======================

**Secure context:** This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

 The **`Crypto.subtle`** read-only property returns a
 `SubtleCrypto` which can then be used to perform low-level
 cryptographic operations.

Value
-----

 A `SubtleCrypto` object you can use to interact with the Web Crypto API's
 low-level cryptography features.

Specifications
--------------

| Specification |
| --- |
| Web Cryptography API # Crypto-attribute-subtle |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `Crypto`.
* `SubtleCrypto`.
* Compatibility test page.
* Shim for IE11 and Safari.


IdentityProvider: getUserInfo() static method - Web APIs

IdentityProvider: getUserInfo() static method
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`getUserInfo()`** static method of the `IdentityProvider` interface returns information about a previously signed in user, which can be used to provide a personalized welcome message and sign-in button. This method has to be called from within an identity provider (IdP)-origin `<iframe>` so that RP scripts cannot access the data. This must occur after a previously signed in user returns to the relying party (RP) site.

This pattern is already common on sites that use identity federation for sign-in, but `getUserInfo()` provides a way to achieve it without relying on third-party cookies.

Usage notes
-----------

When `getUserInfo()` is called, the browser will make a request to the IdP accounts list endpoint for the user information only when both the below conditions are true:

* The user has previously signed in to the RP with the IdP via FedCM on the same browser instance, and the data hasn't been cleared.
* The user is signed in to the IdP on the same browser instance.

`getUserInfo()` must be called from within an embedded `<iframe>`, and the embedded site's origin must match the `configURL` of the IdP. In addition, the embedding HTML must explicitly allow its use via the `identity-credentials-get` Permissions-Policy:

```html
<iframe
 src="https://idp.example/signin"
 allow="identity-credentials-get"></iframe>
```

Syntax
------

```js
IdentityProvider.getUserInfo(config)
```

### Parameters

`config`

A configuration object, which can contain the following properties:

`configURL`

The URL of the configuration file for the identity provider from which you want to get user information.

`clientId`

The RP's client identifier issued by the IdP.

### Return value

A `Promise` that fulfills with an array of objects, each containing information representing a separate user account. Each object contains the following properties:

`email`

A string representing the user's email address.

`name`

A string representing the user's full name.

`givenName`

A string representing the user's given (nick or abbreviated) name.

`picture`

A string representing the URL of the user's profile picture.

### Exceptions

`InvalidStateError` `DOMException`

Thrown if the provided `configURL` is invalid or if the embedded document's origin does not match the `configURL`.

`NetworkError` `DOMException`

Thrown if the browser is unable to connect to the IdP or if `getUserInfo()` is invoked from the top-level document.

`NotAllowedError` `DOMException`

Thrown if the embedding `<iframe>` does not have a `identity-credentials-get` Permissions-Policy set to allow the use of `getUserInfo()` or if the FedCM API is disabled globally by a policy set on the top-level document.

Examples
--------

```js
// Iframe displaying a page from the https://idp.example origin
const user_info = await IdentityProvider.getUserInfo({
  configUrl: "https://idp.example/fedcm.json",
  clientId: "client1234",
});

// IdentityProvider.getUserInfo() returns an array of user information.
if (user_info.length > 0) {
  // Returning accounts should be first, so the first account received
  // is guaranteed to be a returning account
  const name = user_info[0].name;
  const given_name = user_info[0].given_name;
  const display_name = given_name ? given_name : name;
  const picture = user_info[0].picture;
  const email = user_info[0].email;

  // ...

  // Render the personalized sign-in button using the information above
}
```

Specifications
--------------

| Specification |
| --- |
| Federated Credential Management API # dom-identityprovider-getuserinfo |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Federated Credential Management API on developer.chrome.com (2023)


TaskAttributionTiming: containerId property - Web APIs

TaskAttributionTiming: containerId property
===========================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`containerId`** readonly property of the `TaskAttributionTiming` interface returns the container's `id`
 attribute. A container is the iframe, embed or object etc. that is being implicated, on the whole, for a long task.

Value
-----

A string containing the container's `id` HTML content attribute.

Specifications
--------------

| Specification |
| --- |
| Long Tasks API # dom-taskattributiontiming-containerid |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


TaskAttributionTiming: containerSrc property - Web APIs

TaskAttributionTiming: containerSrc property
============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`containerSrc`** readonly property of the `TaskAttributionTiming` interface returns the container's `src`
 attribute. A container is the iframe, embed or object etc. that is being implicated, on the whole, for a long task.

Value
-----

A string containing the container's `src` attribute (e.g. `<iframe src="url.html"`).

Specifications
--------------

| Specification |
| --- |
| Long Tasks API # dom-taskattributiontiming-containersrc |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


TaskAttributionTiming: containerName property - Web APIs

TaskAttributionTiming: containerName property
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

 The **`containerName`** readonly property of the `TaskAttributionTiming` interface returns the container's `name`
 attribute. A container is the iframe, embed or object etc. that is being implicated, on the whole, for a long task.

Value
-----

A string containing the container's `name` HTML content attribute (e.g. `<iframe name="myIframe"` or `<object name="myObject"`).

Specifications
--------------

| Specification |
| --- |
| Long Tasks API # dom-taskattributiontiming-containername |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


TaskAttributionTiming: containerType property - Web APIs

TaskAttributionTiming: containerType property
=============================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`containerType`** readonly property of the `TaskAttributionTiming` interface returns the type of the container, one of `iframe`, `embed`, or `object`.

Value
-----

A string containing the container's type, one of `iframe`, `embed`, or `object`. If no type can be determined, `window` will be returned.

Specifications
--------------

| Specification |
| --- |
| Long Tasks API # dom-taskattributiontiming-containertype |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


TaskAttributionTiming: toJSON() method - Web APIs

TaskAttributionTiming: toJSON() method
======================================

**Experimental:** **This is an experimental technology**
Check the Browser compatibility table carefully before using this in production.

The **`toJSON()`** method of the `TaskAttributionTiming` interface is a serializer; it returns a JSON representation of the `TaskAttributionTiming` object.

Syntax
------

```js
toJSON()
```

### Parameters

None.

### Return value

A `JSON` object that is the serialization of the `TaskAttributionTiming` object.

Examples
--------

### Using the toJSON method

In this example, calling `entry.toJSON()` returns a JSON representation of the `TaskAttributionTiming` object.

```js
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    console.log(entry.toJSON());
  });
});

observer.observe({ type: "taskattribution", buffered: true });
```

This would log a JSON object like so:

```json
{
  "name": "unknown",
  "entryType": "taskattribution",
  "startTime": 0,
  "duration": 0,
  "containerType": "window",
  "containerSrc": "",
  "containerId": "",
  "containerName": ""
}
```

To get a JSON string, you can use `JSON.stringify(entry)` directly; it will call `toJSON()` automatically.

Specifications
--------------

| Specification |
| --- |
| Long Tasks API # dom-taskattributiontiming-tojson |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `JSON`


OscillatorNode: frequency property - Web APIs

OscillatorNode: frequency property
==================================

The **`frequency`** property of the `OscillatorNode` interface is an a-rate `AudioParam` representing the frequency of oscillation in hertz.

**Note:** though the `AudioParam` returned is read-only, the value it represents is not.

Value
-----

An a-rate `AudioParam`.

Examples
--------

The following example shows basic usage of an `AudioContext` to create an oscillator node. For an applied example, check out our Violent Theremin demo (see app.js for relevant code).

```js
// create web audio api context
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// create Oscillator node
const oscillator = audioCtx.createOscillator();

oscillator.type = "square";
oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // value in hertz
oscillator.start();
```

Specifications
--------------

| Specification |
| --- |
| Web Audio API # dom-oscillatornode-frequency |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using the Web Audio API


OscillatorNode: setPeriodicWave() method - Web APIs

OscillatorNode: setPeriodicWave() method
========================================

 The **`setPeriodicWave()`** method of the `OscillatorNode` interface is used to point to a `PeriodicWave`
 defining a periodic waveform that can be used to shape the oscillator's output, when
 `type` is `custom`.

Syntax
------

```js
setPeriodicWave(wave)
```

### Parameters

`wave`

 A `PeriodicWave` object representing the waveform to use as the shape
 of the oscillator's output.

### Return value

None (`undefined`).

Examples
--------

 The following example illustrates simple usage of `createPeriodicWave()`,
 recreating a sine wave from a periodic wave.

```js
const real = new Float32Array(2);
const imag = new Float32Array(2);
const ac = new AudioContext();
const osc = ac.createOscillator();

real[0] = 0;
imag[0] = 0;
real[1] = 1;
imag[1] = 0;

const wave = ac.createPeriodicWave(real, imag);

osc.setPeriodicWave(wave);

osc.connect(ac.destination);

osc.start();
osc.stop(2);
```

 This works because a sound that contains only a fundamental tone is by definition a
 sine wave.

 Here, we create a `PeriodicWave` with two values. The first value is the DC
 offset, which is the value at which the oscillator starts. 0 is good here, because we
 want to start the curve at the middle of the [-1.0; 1.0] range.

 The second and subsequent values are sine and cosine components. You can think of it as
 the result of a Fourier transform, where you get frequency domain values from time
 domain value. Here, with `createPeriodicWave()`, you specify the frequencies,
 and the browser performs an inverse Fourier transform to get a time domain buffer for
 the frequency of the oscillator. Here, we only set one component at full volume (1.0) on
 the fundamental tone, so we get a sine wave.

Specifications
--------------

| Specification |
| --- |
| Web Audio API # dom-oscillatornode-setperiodicwave |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using the Web Audio API
* AudioContext.createPeriodicWave


OscillatorNode: OscillatorNode() constructor - Web APIs

OscillatorNode: OscillatorNode() constructor
============================================

 The **`OscillatorNode()`** constructor of the Web Audio API creates a new
 `OscillatorNode` object which is an `AudioNode` that
 represents a periodic waveform, like a sine wave, optionally setting the node's
 properties' values to match values in a specified object.

 If the default values of the properties are acceptable, you can optionally use the
 `BaseAudioContext.createOscillator()` factory method instead; see
 Creating an AudioNode.

Syntax
------

```js
new OscillatorNode(context, options)
```

### Parameters

`context`

A reference to an `AudioContext`.

`options` Optional

 An object whose properties specify the initial values for the oscillator node's
 properties. Any properties omitted from the object will take on the default value
 as documented.

`type`

 The shape of the wave produced by the node. Valid values are
 '`sine`', '`square`', '`sawtooth`',
 '`triangle`' and '`custom`'. The default is
 '`sine`'.

`detune`

 A detuning value (in cents) which will offset
 the `frequency` by the given amount. Its default is 0.

`frequency`

 The frequency (in hertz) of the periodic
 waveform. Its default is 440.

`periodicWave`

 An arbitrary period waveform described by a `PeriodicWave`
 object.

`channelCount`

 Represents an integer used to determine how many channels are used when up-mixing and down-mixing connections to any inputs to the node. (See
 `AudioNode.channelCount` for more information.) Its usage and precise
 definition depend on the value of `channelCountMode`.

`channelCountMode`

 Represents an enumerated value describing the way channels must be matched between
 the node's inputs and outputs. (See `AudioNode.channelCountMode` for more
 information including default values.)

`channelInterpretation`

 Represents an enumerated value describing the meaning of the channels. This
 interpretation will define how audio up-mixing and down-mixing will happen.
 The possible values are `"speakers"` or `"discrete"`. (See
 `AudioNode.channelCountMode` for more information including default
 values.)

### Return value

A new `OscillatorNode` object instance.

Specifications
--------------

| Specification |
| --- |
| Web Audio API # dom-oscillatornode-oscillatornode |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.