Selection: setBaseAndExtent() method - Web APIs

Selection: setBaseAndExtent() method
====================================

 The **`setBaseAndExtent()`** method of the
 `Selection` interface sets the selection to be a range including all or
 parts of two specified DOM nodes, and any content located between them.

Syntax
------

```js
setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)
```

### Parameters

`anchorNode`

The node at the start of the selection.

`anchorOffset`

 The number of child nodes from the start of the anchor node that should be excluded
 from the selection. So for example, if the value is 0 the whole node is included. If
 the value is 1, the whole node minus the first child node is included. And so on.

 If `anchorNode` is a `Text` node, the offset refers to the number of
 characters from the start of the `Node.textContent` that should be
 excluded from the selection.

`focusNode`

The node at the end of the selection.

`focusOffset`

 The number of child nodes from the start of the focus node that should be included
 in the selection. So for example, if the value is 0 the whole node is excluded. If the
 value is 1, the first child node is included. And so on.

 If `focusNode` is a `Text` node, the offset refers to the number of
 characters from the start of the `Node.textContent` that should be
 included in the selection.

**Note:** If the focus position appears before the anchor position in
 the document, the direction of the selection is reversed — the caret is placed at the
 beginning of the text rather the end, which matters for any keyboard command that
 might follow. For example, `Shift` + `➡` would cause the selection
 to narrow from the beginning rather than grow at the end.

### Return value

None (`undefined`).

### Exceptions

`IndexSizeError` `DOMException`

Thrown if `anchorOffset` is larger than the number of child nodes inside `anchorNode`, or if `focusOffset` is larger than the number of child nodes inside `focusNode`.

Examples
--------

 In this example, we have two paragraphs containing spans, each one containing a single
 word. The first one is set as the `anchorNode` and the second is set as the
 `focusNode`. We also have an additional paragraph that sits in between the
 two nodes.

 Next, we have two form inputs that allow you to set the `anchorOffset` and
 `focusOffset` — they both have a default value of 0.

 We also have a button that when pressed invokes a function that runs the
 `setBaseAndExtent()` method with the specified offsets, and copies the
 selection into the output paragraph at the very bottom of the HTML.

```html
<h1>setBaseAndExtent example</h1>
<div>
  <p class="one">
    <span>Fish</span><span>Dog</span><span>Cat</span><span>Bird</span>
  </p>
  <p>MIDDLE</p>
  <p class="two">
    <span>Car</span><span>Bike</span><span>Boat</span><span>Plane</span>
  </p>
</div>

<div>
  <p>
    <label for="aOffset">Anchor offset</label>
    <input id="aOffset" name="aOffset" type="number" value="0" />
  </p>
  <p>
    <label for="fOffset">Focus offset</label>
    <input id="fOffset" name="fOffset" type="number" value="0" />
  </p>
  <p><button>Capture selection</button></p>
</div>

<p><strong>Output</strong>: <span class="output"></span></p>
```

**Note:** There is intentionally no whitespace between the `<p class="one">` and `<p class="two">` start tags and the `<span>` start tags which follow them — to avoid the presence of text nodes that would affect the number of child nodes expected. (Even though those text nodes would be whitespace-only, they would still be additional child nodes; find out more from the `Node.firstChild` example).

The JavaScript looks like so:

```js
const one = document.querySelector(".one");
const two = document.querySelector(".two");

const aOffset = document.getElementById("aOffset");
const fOffset = document.getElementById("fOffset");

const button = document.querySelector("button");

const output = document.querySelector(".output");

let selection;

button.onclick = () => {
  try {
    selection = document.getSelection();
    selection.setBaseAndExtent(one, aOffset.value, two, fOffset.value);
    const text = selection.toString();
    output.textContent = text;
  } catch (e) {
    output.textContent = e.message;
  }
};
```

 Play with the live example below, setting different offset values to see how this
 affects the selection.

**Note:** You can find this example on GitHub (see it live also.)

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

| Specification |
| --- |
| Selection API # dom-selection-setbaseandextent |

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

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

See also
--------

* `Selection`


Selection: collapseToStart() method - Web APIs

Selection: collapseToStart() method
===================================

 The **`Selection.collapseToStart()`** method collapses the
 selection to the start of the first range in the selection. If the content of the
 selection is focused and editable, the caret will blink there.

Syntax
------

```js
collapseToStart()
```

### Parameters

None.

### Return value

None (`undefined`).

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

| Specification |
| --- |
| Selection API # dom-selection-collapsetostart |

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

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

See also
--------

* `Selection`, the interface it belongs to.


MutationRecord: oldValue property - Web APIs

MutationRecord: oldValue property
=================================

The `MutationRecord` read-only property **`oldValue`** contains the character data or attribute value of an observed node before it was changed.

Value
-----

A string representing the old value of an attribute which has been changed, if:

* the `attributeOldValue` parameter to `MutationObserver.observe()` is `true`
* the `attributes` parameter to `MutationObserver.observe()` is `true` or omitted
* the mutation `type` is `attributes`.

A string representing the old value of a `CharacterData` node that has been changed, if:

* the `characterDataOldValue` parameter to `MutationObserver.observe()` is `true`
* the `characterData` parameter to `MutationObserver.observe()` is `true` or omitted
* the mutation `type` is `characterData`.

Otherwise this property is `null`.

Examples
--------

### Show old color value

In the following example, there is a button that changes the color of an `h1` to a random new color. A `MutationObserver` is used to observe the target node (`h1`) for changes to the attribute; when a change is detected, the observer calls a function, `logOldValue()`.

The `logOldValue()` function is passed the `mutationRecords` array, which contains the `MutationRecord` objects. The `oldValue` property of the `MutationRecord` object is then displayed, in the color of the old value.

#### HTML

```html
<h1 id="h1" style="color: rgb(0 0 0);">Hi, Mom!</h1>
<button id="changeColorButton">Change color</button>
<p id="log"></p>
```

#### JavaScript

```js
const h1 = document.getElementById("h1");
const changeValueButton = document.getElementById("changeColorButton");
const log = document.getElementById("log");

changeColorButton.addEventListener("click", () => {
  // Random 6 character hexadecimal number to use as the hex color value
  const newColor = Math.floor(Math.random() \* 16777215).toString(16);
  h1.style.color = `#${newColor}`;
});

function logOldValue(mutationRecordArray) {
  for (const record of mutationRecordArray) {
    log.textContent = `Old value: ${record.oldValue}`;
    log.style.cssText = record.oldValue;
  }
}

const observer = new MutationObserver(logOldValue);
observer.observe(h1, {
  attributes: true,
  attributeOldValue: true,
});
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-oldvalue② |

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

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


MutationRecord: nextSibling property - Web APIs

MutationRecord: nextSibling property
====================================

The `MutationRecord` read-only property **`nextSibling`** is the next sibling of an added or removed child node of the `target` of a `MutationObserver`.

Value
-----

If a node is added to or removed from the `target` of a `MutationObserver`, the value is the `Node` that is the next sibling of the added or removed node: that is, the node immediately following this one in the parent's `childNodes` list.

The value is `null` if there are no added or removed nodes, or if the node is the last child of its parent.

Examples
--------

### Log the next sibling of a mutation

This adds a node every time you click the button, but it adds the node at the *start of the target*, not the end. Then the observer logs the `textContent` of the `nextSibling` of the added node.

#### HTML

```html
<button id="add-nodes">Add a node</button>
<button id="reset">Reset</button>

<pre id="log" class="log">Next sibling of added node:</pre>
<div id="target"><p>Node #0</p></div>
```

```
.log {
  border: 1px dotted black;
  padding: 0.5rem;
}
```

#### JavaScript

```js
const addNodes = document.querySelector("#add-nodes");
const reset = document.querySelector("#reset");
const target = document.querySelector("#target");
let nodeNumber = 1;

addNodes.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Node #${nodeNumber}`;
  nodeNumber++;
  target.insertBefore(newPara, target.firstChild);
});

reset.addEventListener("click", () => self.location.reload());

function logNextSibling(records) {
  for (const record of records) {
    if (record.type === "childList") {
      for (const newNode of record.addedNodes) {
        log.textContent = `Next sibling of added node: ${record.nextSibling?.textContent}`;
      }
    }
  }
}

const observer = new MutationObserver(logNextSibling);
observer.observe(target, { childList: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-nextsibling② |

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

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


MutationRecord: addedNodes property - Web APIs

MutationRecord: addedNodes property
===================================

The `MutationRecord` read-only property **`addedNodes`** is a `NodeList` of nodes added to a target node by a mutation observed with a `MutationObserver`.

Value
-----

A `NodeList` containing the nodes added to the target of the mutation observed by the `MutationObserver`.

Examples
--------

### Update when adding a node

In the following example, there are two buttons: one to add new nodes to a target node, and one to remove them. A `MutationObserver` is used to observe the target node for changes; when a change is detected, the observer calls a function, `logNewNodes()`.

The `logNewNodes()` function checks that the MutationRecord's `type` is `childList`, which means that the target node's children have changed. If the type is `childlist` the function updates the total number of new nodes that have been added. However, note that clicking the "Remove a node" button will not increment the total number of new nodes, because in this case `record.addedNodes` will have a length of `0`.

#### HTML

```html
<button id="add-nodes">Add a node</button>
<button id="remove-nodes">Remove a node</button>
<button id="reset">Reset</button>

<pre id="counter">Total added nodes: 0</pre>
<div id="target"></div>
```

```
#counter {
  border: 1px dotted black;
  padding: 0.5rem;
}
```

#### JavaScript

```js
const addNodes = document.querySelector("#add-nodes");
const removeNodes = document.querySelector("#remove-nodes");
const reset = document.querySelector("#reset");
const counter = document.querySelector("#counter");
const target = document.querySelector("#target");
let totalAddedNodes = 0;

addNodes.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Current time: ${Date.now()}`;
  target.appendChild(newPara);
});

removeNodes.addEventListener("click", () => {
  const lastChild = target.lastChild;
  if (lastChild) {
    target.removeChild(lastChild);
  }
});

reset.addEventListener("click", () => self.location.reload());

function logNewNodes(records) {
  for (const record of records) {
    // Check if the childlist of the target node has been mutated
    if (record.type === "childList") {
      totalAddedNodes = totalAddedNodes + record.addedNodes.length;
      // Log the number of nodes added
      counter.textContent = `Total added nodes: ${totalAddedNodes}`;
    }
  }
}

const observer = new MutationObserver(logNewNodes);
observer.observe(target, { childList: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-addednodes② |

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

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


MutationRecord: removedNodes property - Web APIs

MutationRecord: removedNodes property
=====================================

The `MutationRecord` read-only property **`removedNodes`** is a `NodeList` of nodes removed from a target node by a mutation observed with a `MutationObserver`.

Value
-----

A `NodeList` containing the nodes removed from the target of the mutation observed by the `MutationObserver`.

Examples
--------

### Observing removed nodes

In the following example, there are two buttons: one to add new nodes to a target node, and one to remove them. A `MutationObserver` is used to observe the target node for changes; when a change is detected, the observer calls a function, `logRemovedNodes()`.

The `logRemovedNodes()` function checks that the MutationRecord's `type` is `childList`, which means that the target node's children have changed. If the type is `childlist` the function updates the total number of nodes that have been removed. However, note that clicking the "Add a node" button will not increment the total number of removed nodes, because in this case `record.removedNodes` will have a length of `0`.

#### HTML

```html
<button id="add-nodes">Add a node</button>
<button id="remove-nodes">Remove a node</button>
<button id="reset">Reset</button>

<pre id="counter">Total removed nodes: 0</pre>
<div id="target"></div>
```

```
#counter {
  border: 1px dotted black;
  padding: 0.5rem;
}
```

#### JavaScript

```js
const addNodes = document.querySelector("#add-nodes");
const removeNodes = document.querySelector("#remove-nodes");
const reset = document.querySelector("#reset");
const counter = document.querySelector("#counter");
const target = document.querySelector("#target");
let totalRemovedNodes = 0;

addNodes.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Current time: ${Date.now()}`;
  target.appendChild(newPara);
});

removeNodes.addEventListener("click", () => {
  const lastChild = target.lastChild;
  if (lastChild) {
    target.removeChild(lastChild);
  }
});

reset.addEventListener("click", () => self.location.reload());

function logRemovedNodes(records) {
  for (const record of records) {
    // Check if the childlist of the target node has been mutated
    if (record.type === "childList") {
      totalRemovedNodes = totalRemovedNodes + record.removedNodes.length;
      // Log the number of nodes added
      counter.textContent = `Total removed nodes: ${totalRemovedNodes}`;
    }
  }
}

const observer = new MutationObserver(logRemovedNodes);
observer.observe(target, { childList: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-removednodes② |

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

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


MutationRecord: type property - Web APIs

MutationRecord: type property
=============================

The `MutationRecord` read-only property **`type`** is the type of the `MutationRecord` observed by a `MutationObserver`.

Value
-----

The property is set to the type of the mutation as a string. The value can be one of the following:

* `attributes` if the mutation was an attribute mutation.
* `characterData` if it was a mutation to a `CharacterData` node.
* `childList` if the mutation a mutation to the tree of nodes.
Examples
--------

### Log the type of a mutation

The following example gives you two buttons to manipulate the DOM. The first button adds a new node to the example, and the second button changes the `color` attribute of all the added nodes. A `MutationObserver` is created to observe it all, and the observer is set to log the `type` of the mutation record to `#log`.

You'll notice the when you add a node, the `type` is `childList`, and when you change the `color` attribute, the `type` is `attributes`.

#### HTML

```html
<button id="add-nodes">Add a node</button>
<button id="set-attribute">Change the color</button>

<button id="reset">Reset</button>

<pre id="log">Mutation type:</pre>
<div id="target"><p>Node #0</p></div>
```

```
#log {
  border: 1px dotted black;
  padding: 0.5rem;
}

.blue {
  color: blue;
}

.red {
  color: red;
}
```

#### JavaScript

```js
const addNodes = document.querySelector("#add-nodes");
const setAttribute = document.querySelector("#set-attribute");
const reset = document.querySelector("#reset");
const log = document.querySelector("#log");
const target = document.querySelector("#target");
let nodeNumber = 1;

addNodes.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Node #${nodeNumber}`;
  nodeNumber++;
  target.appendChild(newPara);
});

setAttribute.addEventListener("click", () => {
  if (target.getAttribute("class") === "red") {
    target.setAttribute("class", "blue");
  } else {
    target.setAttribute("class", "red");
  }
});

reset.addEventListener("click", () => self.location.reload());

function logMutationType(records) {
  for (const record of records) {
    log.textContent = `Mutation type: ${record.type}`;
  }
}

const observer = new MutationObserver(logMutationType);
observer.observe(target, { childList: true, attributes: true, subtree: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-type② |

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

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


MutationRecord: target property - Web APIs

MutationRecord: target property
===============================

The `MutationRecord` read-only property **`target`** is the target (i.e. the mutated/changed node) of a mutation observed with a `MutationObserver`.

Value
-----

The `Node` that the mutation affected.

* If the record's `type` is `attributes`, this is the `Element` whose attributes changed.
* If the record's `type` is `characterData`, this is the `CharacterData` node.
* If the record's `type` is `childList`, this is the `Node` whose children changed.
Examples
--------

### Logging the target of a mutation

In the following example, there are two divs: a red div (`#red-div`) and a blue div (`#blue-div`), inside a container div `#container`. A `MutationObserver` is created to observe the container. The observer is observing changes to the childlist, and also has `subtree: true` so it will observe changes to the children of the container's children.

The observer callback logs the `target` of the mutation record. When we add nodes to the `#red-div` or the `#blue-div`, the `target` will be the `#red-div` or the `#blue-div`, respectively.

#### HTML

```html
<pre id="log">Target of mutation:</pre>
<button id="add-nodes-to-red-div">Add a node to red div</button>
<button id="add-nodes-to-blue-div">Add a node to blue div</button>
<button id="reset">Reset</button>
<div id="container">
  <div id="red-div"></div>
  <div id="blue-div"></div>
</div>
```

```
#log {
  border: 1px dotted black;
  padding: 0.5rem;
}

#red-div {
  border: 1px solid red;
  margin-top: 0.5rem;
  margin-right: 0.5rem;
  padding: 0.5rem;
  overflow: auto;
}

#blue-div {
  border: 1px solid blue;
  margin-top: 0.5rem;
  margin-left: 0.5rem;
  padding: 0.5rem;
  overflow: auto;
}

#container {
  display: grid;
  grid-template-columns: 50% auto;
}
```

#### JavaScript

```js
const container = document.querySelector("#container");
const redDiv = document.querySelector("#red-div");
const blueDiv = document.querySelector("#blue-div");
const addToRed = document.querySelector("#add-nodes-to-red-div");
const addToBlue = document.querySelector("#add-nodes-to-blue-div");
const reset = document.querySelector("#reset");
const log = document.querySelector("#log");

addToRed.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Current time: ${Date.now()}`;
  redDiv.appendChild(newPara);
});

addToBlue.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Current time: ${Date.now()}`;
  blueDiv.appendChild(newPara);
});

reset.addEventListener("click", () => self.location.reload());

function logMutationTarget(records) {
  for (const record of records) {
    log.textContent = `Target of mutation: ${record.target.id}`;
  }
}

const observer = new MutationObserver(logMutationTarget);
observer.observe(container, { childList: true, subtree: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-target② |

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

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


MutationRecord: attributeNamespace property - Web APIs

MutationRecord: attributeNamespace property
===========================================

The `MutationRecord` read-only property **`attributeNamespace`** is the namespace of the mutated attribute in the `MutationRecord` observed by a `MutationObserver`.

Value
-----

If the record's `type` is `attributes`, the property is a string representing the namespace of the mutated attribute of the mutation target. The value is `null` otherwise.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-attributenamespace② |

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

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


MutationRecord: previousSibling property - Web APIs

MutationRecord: previousSibling property
========================================

The `MutationRecord` read-only property **`previousSibling`** is the previous sibling of an added or removed child node of the `target` of a `MutationObserver`.

Value
-----

If a node is added to or removed from the `target` of a `MutationObserver`, the value is the `Node` that is the previous sibling of the added or removed node: that is, the node immediately before this one in the parent's `childNodes` list.

The value is `null` if there are no added or removed nodes, or if the node is the first child of its parent.

Examples
--------

### Log the previous sibling of a mutation

This adds a node every time you click the button. Then the observer logs the `textContent` of the `previousSibling` of the added node.

#### HTML

```html
<button id="add-nodes">Add a node</button>
<button id="reset">Reset</button>

<pre id="log" class="log">Previous sibling of added node:</pre>
<div id="target"><p>Node #0</p></div>
```

```
.log {
  border: 1px dotted black;
  padding: 0.5rem;
}
```

#### JavaScript

```js
const addNodes = document.querySelector("#add-nodes");
const reset = document.querySelector("#reset");
const target = document.querySelector("#target");
let nodeNumber = 1;

addNodes.addEventListener("click", () => {
  const newPara = document.createElement("p");
  newPara.textContent = `Node #${nodeNumber}`;
  nodeNumber++;
  target.appendChild(newPara);
});

reset.addEventListener("click", () => self.location.reload());

function logPreviousSibling(records) {
  for (const record of records) {
    if (record.type === "childList") {
      for (const newNode of record.addedNodes) {
        log.textContent = `Previous sibling of added node: ${newNode.previousSibling?.textContent}`;
      }
    }
  }
}

const observer = new MutationObserver(logPreviousSibling);
observer.observe(target, { childList: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-previoussibling② |

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

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


MutationRecord: attributeName property - Web APIs

MutationRecord: attributeName property
======================================

The `MutationRecord` read-only property **`attributeName`** contains the name of a changed attribute belonging to a node that is observed by a `MutationObserver`.

Value
-----

If the record's `type` is `attributes`, this is a string representing the name of the mutated attribute of the mutation target.

If the record's `type` is not `attributes`, this is `null`.

Examples
--------

### Get last updated attribute name

In the following example, there are four buttons: two change the `style` attribute of the `h1` element, and two change the `class` attribute of the `h1` element. The script uses a `MutationObserver` to detect the changes and will update the text below to the name of the last attribute that was changed.

#### HTML

```html
<h1 class="blue" style="color:black;" id="hiMom">Hi, Mom!</h1>

<button id="redButton">Set class to "red"</button>
<button id="blueButton">Set class to "blue"</button>
<button id="whiteButton">Set style to "color:white;"</button>
<button id="blackButton">Set style to "color:black;"</button>

<p id="log">Updated attribute name:</p>
```

#### CSS

```css
.red {
  background-color: red;
}

.blue {
  background-color: blue;
}
```

#### JavaScript

```js
const hiMom = document.querySelector("#hiMom");
const redButton = document.querySelector("#redButton");
const blueButton = document.querySelector("#blueButton ");
const whiteButton = document.querySelector("#whiteButton");
const blackButton = document.querySelector("#blackButton");
const log = document.querySelector("#log");

redButton.addEventListener("click", () => {
  hiMom.classList.add("red");
  hiMom.classList.remove("blue");
});

blueButton.addEventListener("click", () => {
  hiMom.classList.add("blue");
  hiMom.classList.remove("red");
});

whiteButton.addEventListener("click", () => {
  hiMom.style.color = "white";
});

blackButton.addEventListener("click", () => {
  hiMom.style.color = "black";
});

function logLastAttr(mutationRecordArray) {
  for (const record of mutationRecordArray) {
    if (record.type === "attributes") {
      log.textContent = `Updated attribute name: ${record.attributeName}`;
    }
  }
}

const observer = new MutationObserver(logLastAttr);
observer.observe(hiMom, { attributes: true });
```

#### Result

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-mutationrecord-attributename② |

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

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


DOMTokenList: add() method - Web APIs

DOMTokenList: add() method
==========================

The **`add()`** method of the `DOMTokenList` interface adds the given tokens to the list, omitting any that are already present.

Syntax
------

```js
add(token1)
add(token1, token2)
add(token1, token2, /\* …, \*/ tokenN)
```

### Parameters

`tokenN`

A string representing a token (or tokens) to add to the `DOMTokenList`.

### Return value

None.

### Exceptions

`SyntaxError` `DOMException`

Thrown if one of the arguments is an empty string

`InvalidCharacterError` `DOMException`

Thrown if a token contains ASCII whitespace.

Examples
--------

 In the following example, we retrieve the list of classes set on a `<span>` element as a `DOMTokenList`, using `Element.classList`.
 We then add a new token to the list, and write the list into the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
classes.add("d");
span.textContent = classes;
```

The output looks like this:

You can add multiple tokens as well:

```js
span.classList.add("d", "e", "f");
```

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-add① |

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

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


DOMTokenList: entries() method - Web APIs

DOMTokenList: entries() method
==============================

 The **`entries()`** method of the `DOMTokenList` interface
 returns an `iterator` allowing you
 to go through all key/value pairs contained in this object. The values are
 `Array`s which have [key, value] pairs, each representing a single token.

Syntax
------

```js
entries()
```

### Return value

Returns an `iterator`.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We when retrieve an iterator containing the key/value
 pairs using `entries()`, then iterate through each one using a
 `for...of` loop, writing them to the
 `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
const iterator = classes.entries();

for (const value of iterator) {
  span.textContent += `(${value})`;
}
```

The output looks like this:

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

#### No specification found

No specification data found for `api.DOMTokenList.entries`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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

See also
--------

* `DOMTokenList.foreach()`, `DOMTokenList.keys` and `DOMTokenList.values`.


DOMTokenList: supports() method - Web APIs

DOMTokenList: supports() method
===============================

 The **`supports()`** method of the `DOMTokenList` interface
 returns `true` if a given `token` is in the associated attribute's supported tokens.
 This method is intended to support feature detection.

Syntax
------

```js
supports(token)
```

### Parameters

`token`

A string containing the token to query for.

### Returns

A boolean value indicating whether the token was found.

Example
-------

```js
const iframe = document.getElementById("display");

if (iframe.sandbox.supports("an-upcoming-feature")) {
  // support code for mystery future feature
} else {
  // fallback code
}

if (iframe.sandbox.supports("allow-scripts")) {
  // instruct frame to run JavaScript
  //
  // (NOTE: This feature is well-supported; this is just an example!)
  //
}
```

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-supports① |

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

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


DOMTokenList: item() method - Web APIs

DOMTokenList: item() method
===========================

 The **`item()`** method of the `DOMTokenList` interface returns an item in the list,
 determined by its position in the list, its index.

**Note:** This method is equivalent as the bracket notation.
 So `aList.item(i)` is the same as `aList[i]`.

Syntax
------

```js
tokenList.item(index)
```

### Parameters

`index`

A number representing the index of the item you want to return. If it isn't an integer, only the integer part is considered.

### Return value

 A string representing the returned item,
 or `null` if the number is greater than or equal to the `length` of the list.

### Exceptions

`TypeError`

Thrown if the `index` cannot be converted to an integer.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then retrieve the last item in the list using
 `item(tokenList.length - 1)`, and write it into the
 `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
const item = classes.item(classes.length - 1);
span.textContent = item;
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-item① |

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

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


DOMTokenList: replace() method - Web APIs

DOMTokenList: replace() method
==============================

 The **`replace()`** method of the `DOMTokenList` interface
 replaces an existing token with a new token.
 If the first token doesn't exist, `replace()` returns `false` immediately,
 without adding the new token to the token list.

Syntax
------

```js
replace(oldToken, newToken)
```

### Parameters

`oldToken`

A string representing the token you want to replace.

`newToken`

A string representing the token you want to replace `oldToken` with.

### Return value

 A boolean value, which is `true` if `oldToken` was
 successfully replaced, or `false` if not.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then replace a token in the list, and write the
 list into the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;

const result = classes.replace("c", "z");

span.textContent = result ? classes : "token not replaced successfully";
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-replace① |

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

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


DOMTokenList: remove() method - Web APIs

DOMTokenList: remove() method
=============================

 The **`remove()`** method of the `DOMTokenList` interface
 removes the specified *tokens* from the list.

Syntax
------

```js
remove(token1)
remove(token1, token2)
remove(token1, token2, /\* …, \*/ tokenN)
```

### Parameters

`token1`, …, `tokenN`

 A string representing the token you want to remove from the list.
 If the string is not in the list, no error is thrown, and nothing happens.

### Return value

None (`undefined`).

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then remove a token from the list, and write the
 list into the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<div id="ab" class="a b c"></div>
<div id="a" class="a b c"></div>
```

Now the JavaScript:

```js
const span = document.getElementById("ab");
const classes = span.classList;
classes.remove("c");
span.textContent = classes;
```

 To remove multiple classes at once, you can supply multiple tokens. The order you
 supply the tokens doesn't have to match the order they appear in the list:

```js
const span2 = document.getElementById("a");
const classes2 = span2.classList;

classes2.remove("c", "b");
span2.textContent = classes2;
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-remove① |

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

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


DOMTokenList: value property - Web APIs

DOMTokenList: value property
============================

 The **`value`** property of the `DOMTokenList`
 interface is a stringifier that returns the value of the list serialized as a
 string, or clears and sets the list to the given value.

Value
-----

 A string representing the serialized content of the list.
 Each item is separated by a space.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`, then write the value of the list to the
 `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
span.textContent = classes.value;
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-value② |

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

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


DOMTokenList: contains() method - Web APIs

DOMTokenList: contains() method
===============================

 The **`contains()`** method of the `DOMTokenList` interface
 returns a boolean value — `true` if the underlying list contains the given token,
 otherwise `false`.

Syntax
------

```js
contains(token)
```

### Parameters

`token`

 A string representing the token
 you want to check for the existence of in the list.

### Return value

 A boolean value, which is `true` if the calling list contains
 `token`, otherwise `false`.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then test for the existence of `"c"` in
 the list, and write the result into the `<span>`'s
 `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
span.textContent = span.classList.contains("c")
  ? "The classList contains 'c'"
  : "The classList does not contain 'c'";
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-contains① |

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

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


DOMTokenList: length property - Web APIs

DOMTokenList: length property
=============================

 The read-only **`length`** property of the `DOMTokenList` interface is an `integer` representing the number
 of objects stored in the object.

Value
-----

An positive integer, or `0` if the list is empty.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`, then write the length of the list to the
 `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
const length = classes.length;

span.textContent = `classList length = ${length}`;
```

The output looks like this:

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-length① |

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

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


DOMTokenList: keys() method - Web APIs

DOMTokenList: keys() method
===========================

 The **`keys()`** method of the `DOMTokenList` interface
 returns an iterator allowing to go through all keys contained in this object.
 The keys are unsigned integers.

Syntax
------

```js
keys()
```

### Parameters

None.

### Return value

Returns an iterator.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then retrieve an iterator containing the keys using `keys()`,
 then iterate through those keys using a for...of loop,
 writing each one to the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
const iterator = classes.keys();

for (let value of iterator) {
  span.textContent += `(${value}) `;
}
```

The output looks like this:

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

#### No specification found

No specification data found for `api.DOMTokenList.keys`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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

See also
--------

* `DOMTokenList.entries()`, `DOMTokenList.forEach()` and `DOMTokenList.values`.


DOMTokenList: values() method - Web APIs

DOMTokenList: values() method
=============================

 The **`values()`** method of the `DOMTokenList` interface
 returns an `iterator`
 allowing the caller to go through all values contained in the `DOMTokenList`.
 The individual values are strings.

Syntax
------

```js
tokenList.values()
```

### Parameters

None.

### Return value

Returns an `iterator`.

Examples
--------

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We when retrieve an iterator containing the values
 using `values()`, then iterate through those values using a for...of loop,
 writing each one to the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b c"></span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;
const iterator = classes.values();

for (const value of iterator) {
  span.textContent += `(${value}) `;
}
```

The output looks like this:

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

#### No specification found

No specification data found for `api.DOMTokenList.values`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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


DOMTokenList: forEach() method - Web APIs

DOMTokenList: forEach() method
==============================

 The **`forEach()`** method of the `DOMTokenList` interface
 calls the callback given in parameter once for each value pair in the list, in
 insertion order.

Syntax
------

```js
forEach(callback)
forEach(callback, thisArg)
```

### Parameters

`callback`

The function to execute for each element, eventually taking three arguments:

`currentValue`

The current element being processed in the array.

`currentIndex`

The index of the current element being processed in the array.

`listObj`

The array that `forEach()` is being applied to.

`thisArg` Optional

The value to use as `this` when executing `callback`.

### Return value

None.

Example
-------

 In the following example we retrieve the list of classes set on a
 `<pre>` element as a `DOMTokenList` using
 `Element.classList`. We when retrieve an iterator containing the values
 using `forEach()`, writing each one to the `<pre>`'s
 `Node.textContent` inside the `forEach()` inner function.

### HTML

```html
<pre class="a b c"></pre>
```

### JavaScript

```js
const pre = document.querySelector("pre");
const classes = pre.classList;
const iterator = classes.values();

classes.forEach(function (value, key, listObj) {
  pre.textContent += `(${value} ${key})/${this}\n`;
}, "arg");
```

### Result

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

#### No specification found

No specification data found for `api.DOMTokenList.forEach`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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

See also
--------

* `DOMTokenList.entries()`, `DOMTokenList.keys` and `DOMTokenList.values`.


DOMTokenList: toggle() method - Web APIs

DOMTokenList: toggle() method
=============================

 The **`toggle()`** method of the `DOMTokenList` interface
 removes an existing token from the list and returns `false`.
 If the token doesn't exist it's added and the function returns `true`.

Syntax
------

```js
toggle(token)
toggle(token, force)
```

### Parameters

`token`

A string representing the token you want to toggle.

`force` Optional

 If included, turns the toggle into a one way-only operation.
 If set to `false`, then `token` will *only* be removed, but not added.
 If set to `true`, then `token` will *only* be added, but not removed.

### Return value

 A boolean value, `true` or `false`, indicating whether `token` is in the
 list after the call or not.

Examples
--------

### Toggling a class on click

 In the following example we retrieve the list of classes set on a
 `<span>` element as a `DOMTokenList` using
 `Element.classList`. We then replace a token in the list, and write the
 list into the `<span>`'s `Node.textContent`.

First, the HTML:

```html
<span class="a b">classList is 'a b'</span>
```

Now the JavaScript:

```js
const span = document.querySelector("span");
const classes = span.classList;

span.addEventListener("click", () => {
  const result = classes.toggle("c");
  span.textContent = `'c' ${
 result ? "added" : "removed"
 }; classList is now "${classes}".`;
});
```

The output looks like this and it will change each time you click on the text:

### Setting the force parameter

The second parameter can be used to determine whether the class is included or not. This example would include the 'c' class only if the browser window is over 1000 pixels wide:

```js
span.classList.toggle("c", window.innerWidth > 1000);
```

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-domtokenlist-toggle① |

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

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


Client: postMessage() method - Web APIs

Client: postMessage() method
============================

 The **`postMessage()`** method of the
 `Client` interface allows a service worker to send a message to a client
 (a `Window`, `Worker`, or `SharedWorker`). The
 message is received in the "`message`" event on
 `navigator.serviceWorker`.

Syntax
------

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

### Parameters

`message`

The message to send to the client. This can be any structured-cloneable type.

`options` Optional

An optional object containing a `transfer` field with an array of transferable objects to transfer ownership of. The ownership of these objects is given to the destination side and they are no longer usable on the sending side.

`transferables` Optional

An optional array of transferable objects to transfer ownership of. The ownership of these objects is given to the destination side and they are no longer usable on the sending side.

### Return value

None (`undefined`).

Examples
--------

The code below sends a message from a service worker to a client. The client is fetched using the `get()` method on `clients`, which is a global in service worker scope.

```js
addEventListener("fetch", (event) => {
  event.waitUntil(
    (async () => {
      // Exit early if we don't have access to the client.
      // Eg, if it's cross-origin.
      if (!event.clientId) return;

      // Get the client.
      const client = await self.clients.get(event.clientId);
      // Exit early if we don't get the client.
      // Eg, if it closed.
      if (!client) return;

      // Send a message to the client.
      client.postMessage({
        msg: "Hey I just got a fetch from you!",
        url: event.request.url,
      });
    })(),
  );
});
```

Receiving that message:

```js
navigator.serviceWorker.addEventListener("message", (event) => {
  console.log(event.data.msg, event.data.url);
});
```

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

| Specification |
| --- |
| Service Workers # dom-client-postmessage-message-options |

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

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


Client: url property - Web APIs

Client: url property
====================

 The **`url`** read-only property of the `Client`
 interface returns the URL of the current service worker client.

Value
-----

A string.

Examples
--------

```js
self.addEventListener("notificationclick", (event) => {
  console.log("On notification click: ", event.notification.tag);
  event.notification.close();

  // This looks to see if the current is already open and
  // focuses if it is
  event.waitUntil(
    clients
      .matchAll({
        type: "window",
      })
      .then((clientList) => {
        for (const client of clientList) {
          if (client.url === "/" && "focus" in client) {
            return client.focus();
          }
        }
        if (clients.openWindow) {
          return clients.openWindow("/");
        }
      }),
  );
});
```

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

| Specification |
| --- |
| Service Workers # client-url |

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

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


Client: frameType property - Web APIs

Client: frameType property
==========================

The **`frameType`** read-only property of the `Client` interface indicates the type of browsing context of the current `Client`. This value can be one of `"auxiliary"`, `"top-level"`, `"nested"`, or `"none"`.

Value
-----

One of these four strings: `"auxiliary"`, `"top-level"`, `"nested"`, or `"none"`.

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

| Specification |
| --- |
| Service Workers # client-frametype |

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

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


Client: id property - Web APIs

Client: id property
===================

The **`id`** read-only property of the `Client` interface returns the universally unique identifier of the `Client` object.

Value
-----

A string uniquely identifying the object.

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

| Specification |
| --- |
| Service Workers # client-id |

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

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


Client: type property - Web APIs

Client: type property
=====================

 The **`type`** read-only property of the `Client`
 interface indicates the type of client the service worker is controlling.

Value
-----

A string, representing the client type. The value can be one of

* `"window"`
* `"worker"`
* `"sharedworker"`
Examples
--------

```js
// service worker client (e.g. a document)
function sendMessage(message) {
  return new Promise((resolve, reject) => {
    // note that this is the ServiceWorker.postMessage version
    navigator.serviceWorker.controller.postMessage(message);
    window.serviceWorker.onMessage = (e) => {
      resolve(e.data);
    };
  });
}

// controlling service worker
self.addEventListener("message", (e) => {
  // e.source is a client object
  e.source.postMessage(`Hello! Your message was: ${e.data}`);
  // Let's also post the type value back to the client
  e.source.postMessage(e.source.type);
});
```

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

| Specification |
| --- |
| Service Workers # client-type |

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

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


WebTransportReceiveStream: getStats() method - Web APIs

WebTransportReceiveStream: getStats() method
============================================

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

The **`getStats()`** method of the `WebTransportReceiveStream` interface asynchronously returns an object containing statistics for the current stream.

 The statistics include the total number of ordered bytes that have arrived on this stream (ignoring network overhead, up until the first missing byte) and the total number that have been read by the application.
 It therefore provides a measure of how quickly the application is consuming bytes from the server on this particular stream.

**Note:** This feature is available in Web Workers

Syntax
------

```js
getStats()
```

### Parameters

None.

### Return value

 A `Promise` that resolves to a object containing statistics about the current stream.
 The returned object has the following properties:

`timestamp`

A `DOMHighResTimeStamp` indicating the timestamp at which the statistics were gathered, relative to Jan 1, 1970, UTC.

`bytesReceived`

 A positive integer indicating the number of bytes received by this stream, up to the first missing byte.
 The number does not include any network overhead, and can only increase.

`bytesRead`

 A positive integer indicating the number of bytes the application has read from this `WebTransportReceiveStream` stream.
 This number can only increase, and is always less than or equal to `bytesReceived`.

Examples
--------

 The code snippet below uses `await` to wait on the `Promise` returned by `getStats()`.
 When the promise fulfills, the number of bytes that have not yet been read is logged to the console.

```js
const stats = await stream.getStats();
const unConsumedBytes = stats.bytesReceived - stats.bytesRead;
console.log(`Bytes in reader queue: ${unConsumedBytes}`);
```

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

| Specification |
| --- |
| WebTransport # dom-webtransportreceivestream-getstats |

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

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


MediaDeviceInfo: toJSON() method - Web APIs

MediaDeviceInfo: toJSON() method
================================

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

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

Syntax
------

```js
toJSON()
```

### Parameters

None.

### Return value

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

### Examples

```js
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
  console.log("enumerateDevices() not supported.");
} else {
  // List cameras and microphones.
  navigator.mediaDevices
    .enumerateDevices()
    .then((devices) => {
      devices.forEach((device) => {
        console.log(device.toJSON());
      });
    })
    .catch((err) => {
      console.log(`${err.name}: ${err.message}`);
    });
}
```

This might produce:

```bash
Object { deviceId: "HJtTemQTM64Bivxv3ZEyKjCi1VR8042lPNpmXKObKJE=", kind: "videoinput", label: "", groupId: "Okm2l1YZTrwy8awTxE8QSLNFoVMdIXx++wLh68tbmv0=" }
Object { deviceId: "EqDubLxPlPeW+5w/ereWTF/3EaAMVHh9QBBHkZHiP0k=", kind: "audioinput", label: "", groupId: "Okm2l1YZTrwy8awTxE8QSLNFoVMdIXx++wLh68tbmv0=" }
Object { deviceId: "CanWttL2RnHOiS7FzzYXMIvLqVFE5S06Lfy8H//nhEw=", kind: "audioinput", label: "", groupId: "nOdLNeXGIw9oL9f2wH69SssQpRVs7cmt9jqZrUWgQwI=" }
```

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

| Specification |
| --- |
| Media Capture and Streams # dom-mediadeviceinfo-tojson |

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

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

See also
--------

* `JSON`


MediaDeviceInfo: kind property - Web APIs

MediaDeviceInfo: kind property
==============================

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

 The **`kind`** read-only property of
 the `MediaDeviceInfo` interface returns an enumerated value, that is
 either `"videoinput"`, `"audioinput"` or `"audiooutput"`.

Value
-----

One of `"videoinput"`, `"audioinput"` or `"audiooutput"`.

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

| Specification |
| --- |
| Media Capture and Streams # dom-mediadeviceinfo-kind |

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

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


MediaDeviceInfo: groupId property - Web APIs

MediaDeviceInfo: groupId property
=================================

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

 The **`groupId`** read-only property of
 the `MediaDeviceInfo` interface returns a string that
 is a group identifier.

 Two devices have the same group identifier if they
 belong to the same physical device; for example, a monitor with both a built-in camera
 and microphone.

Value
-----

 A string which uniquely identifies the group of related devices to
 which this device belongs.

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

| Specification |
| --- |
| Media Capture and Streams # dom-mediadeviceinfo-groupid |

Examples
--------

 In this example, we assemble a list of the devices which are part of the same group as
 a given device. This might be used to produce a user interface that gathers associated
 devices together for presentation purposes, or to make it easy for the user to choose to
 use the built-in camera and microphone on the same display at the same time.

```js
const getDeviceGroup = (mainDevInfo) => {
  let devList = [];

  navigator.mediaDevices.enumerateDevices().then((devices) => {
    devices.forEach((device) => {
      if (device.groupId === mainDevInfo.groupId) {
        devList.push(device);
      }
    });
  });

  return devList;
};
```

 The `getDeviceGroup()` function takes as input the
 `MediaDeviceInfo` object describing the device for which a group list is to
 be built. The function starts by initializing the result array, `devList`, to
 be an empty array.

 Then `navigator.mediaDevices.enumerateDevices()` is called to get the list of all media
 devices. Once the promise resolves, we walk the list using `forEach()`. For each device, if its `groupId` matches the main device's `groupId`, we push the
 `MediaDeviceInfo` object onto the list.

 Finally, the list, which now contains a `MediaDeviceInfo` object for each
 device in the same group, is returned to the caller.

 This could be altered easily to either leave out the passed-in device from the returned
 list, or to place it at the top of the list, by comparing the two objects'
 `deviceId` values, only pushing the device onto
 the result list if it doesn't match.

 This version of the example puts the passed-in device at the top of the result list,
 then adds any other members of the group that are found:

```js
const getDeviceGroup = (mainDevInfo) => {
  let devList = [mainDevInfo];

  navigator.mediaDevices.enumerateDevices().then((devices) => {
    devices.forEach((device) => {
      if (
        device.groupId === mainDevInfo.groupId &&
        device.deviceId !== mainDevInfo.deviceId
      ) {
        devList.push(device);
      }
    });
  });

  return devList;
};
```

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

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


MediaDeviceInfo: deviceId property - Web APIs

MediaDeviceInfo: deviceId property
==================================

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

 The **`deviceId`** read-only property
 of the `MediaDeviceInfo` interface returns a string
 that is an identifier for the represented device and is persisted across
 sessions.

 It is un-guessable by other applications, and unique to the origin of
 the calling application. It is reset when the user clears cookies. For private browsing,
 a different identifier is used that is not persisted across sessions.

Value
-----

A string.

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

| Specification |
| --- |
| Media Capture and Streams # dom-mediadeviceinfo-deviceid |

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

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


MediaDeviceInfo: label property - Web APIs

MediaDeviceInfo: label property
===============================

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

 The **`label`** read-only
 property of the `MediaDeviceInfo` interface returns a
 string describing this device (for example
 "External USB Webcam").

 Only available during active `MediaStream`
 use, or when persistent permissions have been granted.

Value
-----

 A string which describes the media device. For security reasons, the
 `label` is always an empty string (`""`) if the user has not
 obtained permission to use at least one media device, either by starting a stream from
 the microphone or camera, or by persistent permissions being granted.

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

| Specification |
| --- |
| Media Capture and Streams # dom-mediadeviceinfo-label |

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

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


Geolocation: clearWatch() method - Web APIs

Geolocation: clearWatch() method
================================

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

The **`clearWatch()`** method of the `Geolocation` interface is used to unregister location/error monitoring handlers previously installed using `Geolocation.watchPosition()`.

Syntax
------

```js
clearWatch(id)
```

### Parameters

`id`

 The ID number returned by the `Geolocation.watchPosition()` method when
 installing the handler you wish to remove.

### Return value

None (`undefined`).

Examples
--------

```js
let id;
let target;
let options;

function success(pos) {
  const crd = pos.coords;

  if (target.latitude === crd.latitude && target.longitude === crd.longitude) {
    console.log("Congratulations, you've reached the target!");
    navigator.geolocation.clearWatch(id);
  }
}

function error(err) {
  console.error(`ERROR(${err.code}): ${err.message}`);
}

target = {
  latitude: 0,
  longitude: 0,
};

options = {
  enableHighAccuracy: false,
  timeout: 5000,
  maximumAge: 0,
};

id = navigator.geolocation.watchPosition(success, error, options);
```

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

| Specification |
| --- |
| Geolocation API # clearwatch-method |

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

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

See also
--------

* Using geolocation
* `Geolocation`
* `Geolocation.watchPosition()`
* `Geolocation.getCurrentPosition()`


Geolocation: watchPosition() method - Web APIs

Geolocation: watchPosition() method
===================================

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

 The **`watchPosition()`** method of the `Geolocation` interface is used to register a handler function that will be called automatically each time the position of the device changes.
 You can also, optionally, specify an error handling callback function.

Syntax
------

```js
watchPosition(success)
watchPosition(success, error)
watchPosition(success, error, options)
```

### Parameters

`success`

A callback function that takes a `GeolocationPosition` object as an input parameter.

`error` Optional

An optional callback function that takes a `GeolocationPositionError` object as an input parameter.

`options` Optional

 An optional object that provides configuration options for the location watch.
 See `Geolocation.getCurrentPosition()` for more details on possible options.

### Return value

 An integer ID that identifies the registered handler.
 The ID can be passed to the `Geolocation.clearWatch()` to unregister the handler.

Examples
--------

```js
let id;
let target;
let options;

function success(pos) {
  const crd = pos.coords;

  if (target.latitude === crd.latitude && target.longitude === crd.longitude) {
    console.log("Congratulations, you reached the target");
    navigator.geolocation.clearWatch(id);
  }
}

function error(err) {
  console.error(`ERROR(${err.code}): ${err.message}`);
}

target = {
  latitude: 0,
  longitude: 0,
};

options = {
  enableHighAccuracy: false,
  timeout: 5000,
  maximumAge: 0,
};

id = navigator.geolocation.watchPosition(success, error, options);
```

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

| Specification |
| --- |
| Geolocation API # watchposition-method |

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

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

See also
--------

* Using the Geolocation API
* The interface it belongs to, `Geolocation`, and the way to access it —
 `Navigator.geolocation`.
* The opposite operation: `Geolocation.clearWatch()`
* A similar method: `Geolocation.getCurrentPosition()`


Geolocation: getCurrentPosition() method - Web APIs

Geolocation: getCurrentPosition() method
========================================

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

The **`getCurrentPosition()`** method of the `Geolocation` interface is used to get the current position of the device.

Syntax
------

```js
getCurrentPosition(success)
getCurrentPosition(success, error)
getCurrentPosition(success, error, options)
```

### Parameters

`success`

 A callback function that takes a `GeolocationPosition` object as its
 sole input parameter.

`error` Optional

 An optional callback function that takes a `GeolocationPositionError`
 object as its sole input parameter.

`options` Optional

An optional object including the following parameters:

`maximumAge` Optional

A positive `long` value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return. If set to `0`, it means that the device cannot use a cached position and must attempt to retrieve the real current position. If set to `Infinity` the device must return a cached position regardless of its age. Default: `0`.

`timeout` Optional

A positive `long` value representing the maximum length of time (in milliseconds) the device is allowed to take in order to return a position. The default value is `Infinity`, meaning that `getCurrentPosition()` won't return until the position is available.

`enableHighAccuracy` Optional

A boolean value that indicates the application would like to receive the best possible results. If `true` and if the device is able to provide a more accurate position, it will do so. Note that this can result in slower response times or increased power consumption (with a GPS chip on a mobile device for example). On the other hand, if `false`, the device can take the liberty to save resources by responding more quickly and/or using less power. Default: `false`.

### Return value

None (`undefined`).

Examples
--------

```js
const options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0,
};

function success(pos) {
  const crd = pos.coords;

  console.log("Your current position is:");
  console.log(`Latitude : ${crd.latitude}`);
  console.log(`Longitude: ${crd.longitude}`);
  console.log(`More or less ${crd.accuracy} meters.`);
}

function error(err) {
  console.warn(`ERROR(${err.code}): ${err.message}`);
}

navigator.geolocation.getCurrentPosition(success, error, options);
```

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

| Specification |
| --- |
| Geolocation API # getcurrentposition-method |

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

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

See also
--------

* Using the Geolocation API
* `Navigator.geolocation`


DeviceMotionEventRotationRate: alpha property - Web APIs

DeviceMotionEventRotationRate: alpha property
=============================================

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

The **`alpha`** read-only property of the `DeviceMotionEventRotationRate` interface indicates the rate of rotation around the Z axis, in degrees per second.

Value
-----

 A `double` indicating the rate of rotation around the Z axis, in degrees per second.
 See Accelerometer values explained for details.

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

| Specification |
| --- |
| DeviceOrientation Event Specification # dom-devicemotioneventrotationrate-alpha |

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

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


DeviceMotionEventRotationRate: beta property - Web APIs

DeviceMotionEventRotationRate: beta property
============================================

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

The **`beta`** read-only property of the `DeviceMotionEventRotationRate` interface indicates the rate of rotation around the X axis, in degrees per second.

Value
-----

 A `double` indicating the rate of rotation around the X axis, in degrees per second.
 See Accelerometer values explained for details.

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

| Specification |
| --- |
| DeviceOrientation Event Specification # dom-devicemotioneventrotationrate-beta |

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

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


DeviceMotionEventRotationRate: gamma property - Web APIs

DeviceMotionEventRotationRate: gamma property
=============================================

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

The **`gamma`** read-only property of the `DeviceMotionEventRotationRate` interface indicates the rate of rotation around the Y axis, in degrees per second.

Value
-----

 A `double` indicating the rate of rotation around the Y axis, in degrees per second.
 See Accelerometer values explained for details.

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

| Specification |
| --- |
| DeviceOrientation Event Specification # dom-devicemotioneventrotationrate-gamma |

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

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


GPUCompilationInfo: messages property - Web APIs

GPUCompilationInfo: messages property
=====================================

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

 The **`messages`** read-only property of the
 `GPUCompilationInfo` interface is an array of `GPUCompilationMessage` objects, each one containing the details of an individual shader compilation message. Messages can be informational, warnings, or errors.

Value
-----

An array of `GPUCompilationMessage` objects.

Examples
--------

See the main `GPUCompilationInfo` page for an example.

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

| Specification |
| --- |
| WebGPU # dom-gpucompilationinfo-messages |

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

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

See also
--------

* The WebGPU API


FileSystemWritableFileStream: seek() method - Web APIs

FileSystemWritableFileStream: seek() method
===========================================

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

The **`seek()`** method of the `FileSystemWritableFileStream` interface updates the current file cursor offset to the position (in bytes) specified when calling the method.

Syntax
------

```js
seek(position)
```

### Parameters

`position`

A number specifying the byte position from the beginning of the file.

### Return value

A `Promise` that returns `undefined`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if `PermissionStatus.state` is not `granted`.

`TypeError`

Thrown if `position` is not a number or not defined.

Examples
--------

The following asynchronous function opens the 'Save File' picker, which returns a `FileSystemFileHandle` once a file is selected. From this, a writable stream is created using the `FileSystemFileHandle.createWritable()` method.

Next, we write to the stream:

1. A text string is written to the stream.
2. The `seek()` method is used to put the cursor at the start of the stream.
3. A second text string is written to the start of the stream, overwriting the first write.

The stream is then closed.

```js
async function saveFile() {
  try {
    // create a new handle
    const newHandle = await window.showSaveFilePicker();

    // create a FileSystemWritableFileStream to write to
    const writableStream = await newHandle.createWritable();

    // write our file
    await writableStream.write("My first file content");
    await writableStream.seek(0);
    await writableStream.write("My second file content");

    // close the file and write the contents to disk.
    await writableStream.close();
  } catch (err) {
    console.error(err.name, err.message);
  }
}
```

If you run the above function and then open the resulting file created on disk, you should see the text "My second file content".

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

| Specification |
| --- |
| File System Standard # api-filesystemwritablefilestream-seek |

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

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

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemWritableFileStream: truncate() method - Web APIs

FileSystemWritableFileStream: truncate() method
===============================================

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

The **`truncate()`** method of the `FileSystemWritableFileStream` interface resizes the file associated with the stream to the specified size in bytes.

If the size specified is larger than the current file size the file is padded with `0x00` bytes.

 The file cursor is also updated when `truncate()` is called.
 If the offset is smaller than the size, it remains unchanged.
 If the offset is larger than size, the offset is set to that size.
 This ensures that subsequent writes do not error.

 No changes are written to the actual file on disk until the stream has been closed.
 Changes are typically written to a temporary file instead.

Syntax
------

```js
truncate(size)
```

### Parameters

`size`

A number specifying the number of bytes to resize the stream to.

### Return value

A `Promise` that returns `undefined`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if `PermissionStatus.state` is not `granted`.

`QuotaExceededError` `DOMException`

Thrown if the new size of the file is larger than the original size of the file, and exceeds the browser's storage quota.

`TypeError`

Thrown if `size` is not a number or not defined.

Examples
--------

The following asynchronous function opens the 'Save File' picker, which returns a `FileSystemFileHandle` once a file is selected. From this, a writable stream is created using the `FileSystemFileHandle.createWritable()` method.

Next, we write to the stream:

1. A text string is written to the stream.
2. The `truncate()` method is used to resize the file to 8 bytes.
3. A second text string is written to the start of the stream, overwriting the first write.

The stream is then closed.

```js
async function saveFile() {
  try {
    // create a new handle
    const newHandle = await window.showSaveFilePicker();

    // create a FileSystemWritableFileStream to write to
    const writableStream = await newHandle.createWritable();

    // write our file
    await writableStream.write("This is my first file content");
    await writableStream.truncate(8);
    await writableStream.write("my second file content");

    // close the file and write the contents to disk.
    await writableStream.close();
  } catch (err) {
    console.error(err.name, err.message);
  }
}
```

If you run the above function and then open the resulting file created on disk, you should see the text "This is my second file content".

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

| Specification |
| --- |
| File System Standard # api-filesystemwritablefilestream-truncate |

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

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

See also
--------

* File System API
* The File System Access API: simplifying access to local files


FileSystemWritableFileStream: write() method - Web APIs

FileSystemWritableFileStream: write() method
============================================

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

The **`write()`** method of the `FileSystemWritableFileStream` interface writes content into the file the method is called on, at the current file cursor offset.

 No changes are written to the actual file on disk until the stream has been closed.
 Changes are typically written to a temporary file instead. This method can also be used to seek to a byte point within the stream and truncate to modify the total bytes the file contains.

Syntax
------

```js
write(data)
```

### Parameters

`data`

Can be one of the following:

* The file data to write, in the form of an `ArrayBuffer`, `TypedArray`, `DataView`, `Blob`, or string.
* An object containing the following properties:

`type`

A string that is one of `"write"`, `"seek"`, or `"truncate"`.

`data`

The file data to write. Can be an `ArrayBuffer`, `TypedArray`, `DataView`, `Blob`, or string. This property is required if `type` is set to `"write"`.

`position`

The byte position the current file cursor should move to if type `"seek"` is used. Can also be set if `type` is `"write"`, in which case the write will start at the specified position.

`size`

A number representing the number of bytes the stream should contain. This property is required if `type` is set to `"truncate"`.

### Return value

A `Promise` that returns `undefined`.

### Exceptions

`NotAllowedError` `DOMException`

Thrown if `PermissionStatus.state` is not `granted`.

`QuotaExceededError` `DOMException`

Thrown if the new size of the file is larger than the original size of the file, and exceeds the browser's storage quota.

`TypeError`

Thrown if `data` is undefined, or if `position` or `size` aren't valid.

Examples
--------

The following asynchronous function opens the 'Save File' picker, which returns a `FileSystemFileHandle` once a file is selected. From this, a writable stream is created using the `FileSystemFileHandle.createWritable()` method.

A text string is then written to the stream, which is subsequently closed.

```js
async function saveFile() {
  try {
    // create a new handle
    const newHandle = await window.showSaveFilePicker();

    // create a FileSystemWritableFileStream to write to
    const writableStream = await newHandle.createWritable();

    // write our file
    await writableStream.write("This is my file content");

    // close the file and write the contents to disk.
    await writableStream.close();
  } catch (err) {
    console.error(err.name, err.message);
  }
}
```

The following examples show different options that can be passed into the `write()` method.

```js
// just pass in the data (no options)
writableStream.write(data);

// writes the data to the stream from the determined position
writableStream.write({ type: "write", position, data });

// updates the current file cursor offset to the position specified
writableStream.write({ type: "seek", position });

// resizes the file to be size bytes long
writableStream.write({ type: "truncate", size });
```

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

| Specification |
| --- |
| File System Standard # api-filesystemwritablefilestream-write |

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

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

See also
--------

* File System API
* The File System Access API: simplifying access to local files


Performance: mark() method - Web APIs

Performance: mark() method
==========================

The **`mark()`** method creates a named `PerformanceMark` object representing a high resolution timestamp marker in the browser's performance timeline.

Syntax
------

```js
mark(name)
mark(name, markOptions)
```

### Parameters

`name`

A string representing the name of the mark. Must not be the same name as one of the properties of the deprecated `PerformanceTiming` interface.

`markOptions` Optional

An object for specifying a timestamp and additional metadata for the mark.

`detail` Optional

Arbitrary metadata to include in the mark. Defaults to `null`. Must be structured-cloneable.

`startTime` Optional

`DOMHighResTimeStamp` to use as the mark time. Defaults to `performance.now()`.

### Return value

The `PerformanceMark` entry that was created.

### Exceptions

* `SyntaxError`: Thrown if the `name` is one of the properties of the deprecated `PerformanceTiming` interface. See the example below.
* `TypeError`: Thrown if `startTime` is negative.
Examples
--------

### Creating named markers

The following example uses `mark()` to create named `PerformanceMark` entries. You can create several marks with the same name. You can also assign them, to have a reference to the `PerformanceMark` object that has been created.

```js
performance.mark("login-started");
performance.mark("login-started");
performance.mark("login-finished");
performance.mark("form-sent");

const videoMarker = performance.mark("video-loaded");
```

### Creating markers with details

The performance mark is configurable using the `markOptions` object where you can put additional information in the `detail` property, which can be of any type.

```js
performance.mark("login-started", {
  detail: "Login started using the login button in the top menu.",
});

performance.mark("login-started", {
  detail: { htmlElement: myElement.id },
});
```

### Creating markers with a different start time

The default timestamp of the `mark()` method is `performance.now()`. You can set it to a different time using the `startTime` option in `markOptions`.

```js
performance.mark("start-checkout", {
  startTime: 20.0,
});

performance.mark("login-button-pressed", {
  startTime: myEvent.timeStamp,
});
```

### Reserved names

Note in order to maintain backwards compatibility, names that are part of the deprecated `PerformanceTiming` interface can't be used. The following example throws:

```js
performance.mark("navigationStart");
// SyntaxError: "navigationStart" is part of
// the PerformanceTiming interface,
// and cannot be used as a mark name
```

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

| Specification |
| --- |
| User Timing # dom-performance-mark |

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

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


Performance: measure() method - Web APIs

Performance: measure() method
=============================

The **`measure()`** method creates a named `PerformanceMeasure` object representing a time measurement between two marks in the browser's performance timeline.

 When measuring between two marks, there is a *start mark* and *end mark*, respectively.
 The named timestamp is referred to as a *measure*.

Syntax
------

```js
measure(measureName)
measure(measureName, startMark)
measure(measureName, startMark, endMark)
measure(measureName, measureOptions)
measure(measureName, measureOptions, endMark)
```

If only `measureName` is specified, the start timestamp is set to zero, and the end timestamp (which is used to calculate the duration) is the value that would be returned by `Performance.now()`.

You can use strings to identify `PerformanceMark` objects as start and end marks.

 To only provide an `endMark`, you need to provide an empty `measureOptions` object:
 `performance.measure("myMeasure", {}, "myEndMarker")`.

### Parameters

`measureName`

A string representing the name of the measure.

`measureOptions` Optional

An object that may contain measure options.

`detail` Optional

Arbitrary metadata to be included in the measure. Defaults to `null`. Must be structured-cloneable.

`start` Optional

Timestamp (`DOMHighResTimeStamp`) to be used as the start time, or string that names a `PerformanceMark` to use for the start time.

If this is a string naming a `PerformanceMark`, then it is defined in the same way as `startMark`.

`duration` Optional

Duration (in milliseconds) between the start and end mark times. If omitted, this defaults to `performance.now()`; the time that has elapsed since the context was created. If provided, you must also specify either `start` or `end` but not both.

`end` Optional

Timestamp (`DOMHighResTimeStamp`) to be used as the end time, or string that names a `PerformanceMark` to use for the end time.

If this is a string naming a `PerformanceMark`, then it is defined in the same way as `endMark`.

`startMark` Optional

A string naming a `PerformanceMark` in the performance timeline. The `PerformanceEntry.startTime` property of this mark will be used for calculating the measure.

`endMark` Optional

 A string naming a `PerformanceMark` in the performance timeline. The `PerformanceEntry.startTime` property of this mark will be used for calculating the measure.
 If you want to pass this argument, you must also pass either `startMark` or an empty `measureOptions` object.

### Return value

The `PerformanceMeasure` entry that was created.

The returned *measure* will have the following property values:

* `entryType` - set to "`measure`".
* `name` - set to the "`name`" argument.
* `startTime` - set to:
    + a `timestamp`, if specified in `measureOptions.start`.
    + the `timestamp` of a start mark, if specified in `measureOptions.start` or `startMark`
    + a timestamp calculated from the `measureOptions.end` and `measureOptions.duration` (if `measureOptions.start` was not specified)
    + 0, if it isn't specified and can't be determined from other values.
* `duration` - set to a `DOMHighResTimeStamp` that is the duration of the measure calculated by subtracting the `startTime` from the end timestamp.
 The end timestamp is one of:
    + a `timestamp`, if specified in `measureOptions.end`.
    + the `timestamp` of an end mark, if one is specified in `measureOptions.end` or `endMark`
    + a timestamp calculated from the `measureOptions.start` and `measureOptions.duration` (if `measureOptions.end` was not specified)
    + the value returned by `Performance.now()`, if no end mark is specified or can be determined from other values.
* `detail` - set to the value passed in `measureOptions`.
### Exceptions

`TypeError`

This can be thrown in any case where the start, end or duration might be ambiguous:

* Both `endMark` and `measureOptions` are specified.
* `measureOptions` is specified with `duration` but without specifying either `start` or `end`.
* `measureOptions` is specified with all of `start`, `end`, and `duration`.

`SyntaxError` `DOMException`

The named mark does not exist.

* An end mark is specified using either `endMark` or `measureOptions.end`, but there is no `PerformanceMark` in the performance buffer with the matching name.
* An end mark is specified using either `endMark` or `measureOptions.end`, but it cannot be converted to match that of a read only attribute in the `PerformanceTiming` interface.
* A start mark is specified using either `startMark` or `measureOptions.start`, but there is no `PerformanceMark` in the performance buffer with the matching name.
* A start mark is specified using either `startMark` or `measureOptions.start`, but it cannot be converted to match that of a read only attribute in the `PerformanceTiming` interface.

`DataCloneError` `DOMException`

The `measureOptions.detail` value is non-`null` and cannot be serialized using the HTML "StructuredSerialize" algorithm.

`RangeError`

The `measureOptions.detail` value is non-`null` and memory cannot be allocated during serialization using the HTML "StructuredSerialize" algorithm.

Examples
--------

### Measuring duration between named markers

Given two of your own markers `"login-started"` and `"login-finished"`, you can create a measurement called `"login-duration"` as shown in the following example. The returned `PerformanceMeasure` object will then provide a `duration` property to tell you the elapsed time between the two markers.

```js
const loginMeasure = performance.measure(
  "login-duration",
  "login-started",
  "login-finished",
);
console.log(loginMeasure.duration);
```

### Measuring duration with custom start and end times

To do more advanced measurements, you can pass a `measureOptions` parameter. For example, you can use the `event.timeStamp` property from a `click` event as the start time.

```js
performance.measure("login-click", {
  start: myClickEvent.timeStamp,
  end: myMarker.startTime,
});
```

### Providing additional measurement details

You can use the `details` property to provide additional information of any type. Maybe you want to record which HTML element was clicked, for example.

```js
performance.measure("login-click", {
  detail: { htmlElement: myElement.id },
  start: myClickEvent.timeStamp,
  end: myMarker.startTime,
});
```

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

| Specification |
| --- |
| User Timing # dom-performance-measure |

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

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


Performance: measureUserAgentSpecificMemory() method - Web APIs

Performance: measureUserAgentSpecificMemory() method
====================================================

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

The **`measureUserAgentSpecificMemory()`** method is used to estimate the memory usage of a web application including all its iframes and workers.

Description
-----------

The browser automatically allocates memory when objects are created and frees it when they are not reachable anymore (garbage collection). This garbage collection (GC) is an approximation since the general problem of determining whether or not a specific piece of memory is still needed is impossible (see also JavaScript Memory Management). Developers need to make sure that objects are garbage collected, memory isn't leaked, and memory usage doesn't grow unnecessarily over time leading to slow and unresponsive web applications. Memory leaks are typically introduced by forgetting to unregister an event listener, not closing a worker, accumulating objects in arrays, and more.

The `measureUserAgentSpecificMemory()` API aggregates memory usage data to help you find memory leaks. It can be used for memory regression detection or for A/B testing features to evaluate their memory impact. Rather than make single calls to this method, it's better to make periodic calls to track how memory usage changes over the duration of a session.

The `byte` values this API returns aren't comparable across browsers or between different versions of the same browser as these are highly implementation dependent. Also, how `breakdown` and `attribution` arrays are provided is up to the browser as well. It is best to not hardcode any assumptions about this data. This API is rather meant to be called periodically (with a randomized interval) to aggregate data and analyze the difference between the samples.

Syntax
------

```js
measureUserAgentSpecificMemory()
```

### Parameters

None.

### Return value

A `Promise` that resolves to an object containing the following properties:

`bytes`

A number representing the total memory usage.

`breakdown`

An `Array` of objects partitioning the total `bytes` and providing attribution and type information. The object contains the following properties:

`bytes`

The size of the memory that this entry describes.

`attribution`

An `Array` of container elements of the JavaScript realms that use the memory. This object has the following properties:

`url`

If this attribution corresponds to a same-origin JavaScript realm, then this property contains the realm's URL. Otherwise it is the string "cross-origin-url".

`container`

An object describing the DOM element that contains this JavaScript realm. This object has the following properties:

`id`

The `id` attribute of the container element.

`src`

The `src` attribute of the container element. If the container element is an `<object>` element, then this field contains the value of the `data` attribute.

`scope`

A string describing the type of the same-origin JavaScript realm. Either `"Window"`, `"DedicatedWorkerGlobalScope"`, `"SharedWorkerGlobalScope"`, `"ServiceWorkerGlobalScope"` or `"cross-origin-aggregated"` for the cross-origin case.

`types`

An array of implementation-defined memory types associated with the memory.

An example return value looks like this:

```js
{
  bytes: 1500000,
  breakdown: [
    {
      bytes: 1000000,
      attribution: [
        {
          url: "https://example.com",
          scope: "Window",
        },
      ],
      types: ["DOM", "JS"],
    },
    {
      bytes: 0,
      attribution: [],
      types: [],
    },
    {
      bytes: 500000,
      attribution: [
        {
          url: "https://example.com/iframe.html"
          container: {
            id: "example-id",
            src: "redirect.html?target=iframe.html",
          },
          scope: "Window",
        }
      ],
      types: ["JS", "DOM"],
    },
  ],
}
```

### Exceptions

`SecurityError` `DOMException`

Thrown if the security requirements for preventing cross-origin information leaks aren't fulfilled.

Security requirements
---------------------

Your site needs to be in a secure context.

Two headers need to be set to cross-origin isolate your site:

* `Cross-Origin-Opener-Policy` with `same-origin` as value (protects your origin from attackers)
* `Cross-Origin-Embedder-Policy` with `require-corp` or `credentialless` as value (protects victims from your origin)

```http
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```

To check if cross origin isolation has been successful, you can test against the `crossOriginIsolated` property available to window and worker contexts:

```js
if (crossOriginIsolated) {
  // Use measureUserAgentSpecificMemory
}
```

Examples
--------

### Monitoring memory usage

The following code shows how to call the `measureUserAgentSpecificMemory()` method once every five minutes at a random interval using Exponential distribution.

```js
function runMemoryMeasurements() {
  const interval = -Math.log(Math.random()) \* 5 \* 60 \* 1000;
  console.log(`Next measurement in ${Math.round(interval / 1000)} seconds.`);
  setTimeout(measureMemory, interval);
}

async function measureMemory() {
  const memorySample = await performance.measureUserAgentSpecificMemory();
  console.log(memorySample);
  runMemoryMeasurements();
}

if (crossOriginIsolated) {
  runMemoryMeasurements();
}
```

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

| Specification |
| --- |
| Measure Memory API # ref-for-dom-performance-measureuseragentspecificmemory⑤ |

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

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

See also
--------

* `setTimeout()`
* Monitor your web page's total memory usage with measureUserAgentSpecificMemory() - web.dev


Performance: navigation property - Web APIs

Performance: navigation property
================================

**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 legacy
 **`Performance.navigation`**
 read-only property returns a `PerformanceNavigation` object representing
 the type of navigation that occurs in the given browsing context, such as the number of
 redirections needed to fetch the resource.

This property is not available in workers.

**Warning:** This property is deprecated in the Navigation Timing Level 2 specification. Please use the
 `PerformanceNavigationTiming` interface instead.

Value
-----

A `PerformanceNavigation` object.

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

 This feature is no longer on track to become a standard, as the Navigation Timing specification has marked it as deprecated.
 Use the `PerformanceNavigationTiming` interface instead.

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

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

See also
--------

* The `Performance` interface it belongs to.