Exemplo de Composição - APIs da Web

Exemplo de Composição
=====================

Esse exemplo demonstra várias operações de composição. A saída se parece assim:

Exemplo de composição
---------------------

Este código configura os valores globais usados pelo restante do programa.

```js
var canvas1 = document.createElement("canvas");
var canvas2 = document.createElement("canvas");
var gco = [
  "Source-over",
  "Source-in",
  "Source-out",
  "Source-atop",
  "Destination-over",
  "Destination-in",
  "Destination-out",
  "Destination-atop",
  "Lighter",
  "Copy",
  "XOR",
  "Multiply",
  "Screen",
  "Overlay",
  "Darken",
  "Lighten",
  "Color-dodge",
  "Color-burn",
  "Hard-light",
  "Soft-light",
  "Difference",
  "Exclusion",
  "HUE",
  "Saturation",
  "Color",
  "Luminosity",
].reverse();
var gcoText = [
  "Essa é a configuração padrão e desenha novas formas sobre o conteúdo da tela (canvas) existente.",
  "A nova forma é desenhada apenas onde a nova forma e a tela (canvas) de destino se sobrepõem. Todo o resto é transparente. ",
  "A nova forma é desenhada onde ela não sobrepõe o conteúdo da tela (canvas) existente.",
  "A nova forma é somente desenahda onde ela sobrepõe o conteúdo da tela (canvas) existente.",
  "Novas formas são desenhadas por trás do conteúdo da tela (canvas) existente.",
  "O conteúdo da tela (canvas) existente é mantido onde ambos, a nova forma e o conteúdo da tela (canvas) existente, se sobrepõe. Todo o resto é transparente.",
  "O conteúdo existente é mantido onde ele não sobrepõe a nova forma.",
  "A tela (canvas) existente só é mantida onde ela sobrepõe a nova forma. A nova forma é desenahda por trás do conteúdo canvas.",
  "Onde ambas formas se sebrepõem a cor é determinada adicionando seus respectivos valores de cores.",
  "Somente a nova forma é mostrada.",
  "Formas são feitas transparentes onde ambos se sobrepõem e todo o resto é desenhado normalmente.",
  "Os pixels da camada superior são multiplicados pelo pixel correspondente da camada inferior. Uma imagem mais escura é o resultado. ",
  "Os pixels são invertidos, multiplicados e invertidos novamente. Uma imagem mais clara é o resultado (oposto de multiplicar)",
  "Uma combinação de multiplicação e tela. As partes escuras na camada base tornam-se mais escuras e as partes claras tornam-se mais claras.",
  "Mantêm os pixels mais escuro de ambas camadas.",
  "Mantêm os pixels mais claro de ambas camadas.",
  "Divide a camada inferior pela camada superior invertida.",
  "Divide a camada inferior invertida pela camada superior e, em seguida, inverte o resultado.",
  "Uma combinação de multiplicação e tela como sobreposição, mas com a camada superior e inferior trocada.",
  "Uma versão mais suave da luz. Preto ou branco puro não resulta em preto ou branco puro.",
  "Subtrai a camada inferior da camada superior ou vice-versa para obter sempre um valor positivo.",
  "Como diferença, mas com menor contraste.",
  "Preserva o luma e o croma da camada inferior, enquanto adota a tonalidade da camada superior.",
  "Preserva o luma e a tonalidade da camada inferior, enquanto adota o croma da camada superior.",
  "Preserva a luma da camada inferior, enquanto adota a tonalidade e o croma da camada superior.",
  "Preserva a tonalidade e o croma da camada inferior, enquanto adota a luma da camada superior.",
].reverse();
var width = 320;
var height = 340;
```

### Programa principal

Quando a página é carregada, esse código é executado para configurar e executar o exemplo:

```js
window.onload = function () {
  // lum em sRGB
  var lum = {
    r: 0.33,
    g: 0.33,
    b: 0.33,
  };
  // redimensiona canvas
  canvas1.width = width;
  canvas1.height = height;
  canvas2.width = width;
  canvas2.height = height;
  lightMix();
  colorSphere();
  runComposite();
  return;
};
```

E esse código, `runComposite ()`, manipula a maior parte do trabalho, contando com várias funções utilitárias para fazer as partes difíceis.

```js
function createCanvas() {
  var canvas = document.createElement("canvas");
  canvas.style.background = "url(" + op_8x8.data + ")";
  canvas.style.border = "1px solid #000";
  canvas.style.margin = "5px";
  canvas.width = width / 2;
  canvas.height = height / 2;
  return canvas;
}

function runComposite() {
  var dl = document.createElement("dl");
  document.body.appendChild(dl);
  while (gco.length) {
    var pop = gco.pop();
    var dt = document.createElement("dt");
    dt.textContent = pop;
    dl.appendChild(dt);
    var dd = document.createElement("dd");
    var p = document.createElement("p");
    p.textContent = gcoText.pop();
    dd.appendChild(p);

    var canvasToDrawOn = createCanvas();
    var canvasToDrawFrom = createCanvas();
    var canvasToDrawResult = createCanvas();

    var ctx = canvasToDrawResult.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas1, 0, 0, width / 2, height / 2);
    ctx.globalCompositeOperation = pop;
    ctx.drawImage(canvas2, 0, 0, width / 2, height / 2);
    ctx.globalCompositeOperation = "source-over";
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText(pop, 5, height / 2 - 5);
    ctx.restore();

    var ctx = canvasToDrawOn.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas1, 0, 0, width / 2, height / 2);
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText("Conteúdo existente", 5, height / 2 - 5);
    ctx.restore();

    var ctx = canvasToDrawFrom.getContext("2d");
    ctx.clearRect(0, 0, width, height);
    ctx.save();
    ctx.drawImage(canvas2, 0, 0, width / 2, height / 2);
    ctx.fillStyle = "rgba(0,0,0,0.8)";
    ctx.fillRect(0, height / 2 - 20, width / 2, 20);
    ctx.fillStyle = "#FFF";
    ctx.font = "14px arial";
    ctx.fillText("Novo conteúdo", 5, height / 2 - 5);
    ctx.restore();

    dd.appendChild(canvasToDrawOn);
    dd.appendChild(canvasToDrawFrom);
    dd.appendChild(canvasToDrawResult);

    dl.appendChild(dd);
  }
}
```

### Funções Utilitárias

O programa depende de várias funções utilitárias.

```js
var lightMix = function () {
  var ctx = canvas2.getContext("2d");
  ctx.save();
  ctx.globalCompositeOperation = "lighter";
  ctx.beginPath();
  ctx.fillStyle = "rgba(255,0,0,1)";
  ctx.arc(100, 200, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.beginPath();
  ctx.fillStyle = "rgba(0,0,255,1)";
  ctx.arc(220, 200, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.beginPath();
  ctx.fillStyle = "rgba(0,255,0,1)";
  ctx.arc(160, 100, 100, Math.PI \* 2, 0, false);
  ctx.fill();
  ctx.restore();
  ctx.beginPath();
  ctx.fillStyle = "#f00";
  ctx.fillRect(0, 0, 30, 30);
  ctx.fill();
};
```

```js
var colorSphere = function (element) {
  var ctx = canvas1.getContext("2d");
  var width = 360;
  var halfWidth = width / 2;
  var rotate = (1 / 360) \* Math.PI \* 2; // per degree
  var offset = 0; // scrollbar offset
  var oleft = -20;
  var otop = -20;
  for (var n = 0; n <= 359; n++) {
    var gradient = ctx.createLinearGradient(
      oleft + halfWidth,
      otop,
      oleft + halfWidth,
      otop + halfWidth,
    );
    var color = Color.HSV\_RGB({ H: (n + 300) % 360, S: 100, V: 100 });
    gradient.addColorStop(0, "rgba(0,0,0,0)");
    gradient.addColorStop(
      0.7,
      "rgba(" + color.R + "," + color.G + "," + color.B + ",1)",
    );
    gradient.addColorStop(1, "rgba(255,255,255,1)");
    ctx.beginPath();
    ctx.moveTo(oleft + halfWidth, otop);
    ctx.lineTo(oleft + halfWidth, otop + halfWidth);
    ctx.lineTo(oleft + halfWidth + 6, otop);
    ctx.fillStyle = gradient;
    ctx.fill();
    ctx.translate(oleft + halfWidth, otop + halfWidth);
    ctx.rotate(rotate);
    ctx.translate(-(oleft + halfWidth), -(otop + halfWidth));
  }
  ctx.beginPath();
  ctx.fillStyle = "#00f";
  ctx.fillRect(15, 15, 30, 30);
  ctx.fill();
  return ctx.canvas;
};
```

```js
// HSV (1978) = H: Hue (tom)
// S: Saturation (Saturação)
// V: Value (Valor)
Color = {};
Color.HSV\_RGB = function (o) {
  var H = o.H / 360,
    S = o.S / 100,
    V = o.V / 100,
    R,
    G,
    B;
  var A, B, C, D;
  if (S == 0) {
    R = G = B = Math.round(V \* 255);
  } else {
    if (H >= 1) H = 0;
    H = 6 \* H;
    D = H - Math.floor(H);
    A = Math.round(255 \* V \* (1 - S));
    B = Math.round(255 \* V \* (1 - S \* D));
    C = Math.round(255 \* V \* (1 - S \* (1 - D)));
    V = Math.round(255 \* V);
    switch (Math.floor(H)) {
      case 0:
        R = V;
        G = C;
        B = A;
        break;
      case 1:
        R = B;
        G = V;
        B = A;
        break;
      case 2:
        R = A;
        G = V;
        B = C;
        break;
      case 3:
        R = A;
        G = B;
        B = V;
        break;
      case 4:
        R = C;
        G = A;
        B = V;
        break;
      case 5:
        R = V;
        G = A;
        B = B;
        break;
    }
  }
  return {
    R: R,
    G: G,
    B: B,
  };
};

var createInterlace = function (size, color1, color2) {
  var proto = document.createElement("canvas").getContext("2d");
  proto.canvas.width = size \* 2;
  proto.canvas.height = size \* 2;
  proto.fillStyle = color1; // top-left
  proto.fillRect(0, 0, size, size);
  proto.fillStyle = color2; // top-right
  proto.fillRect(size, 0, size, size);
  proto.fillStyle = color2; // bottom-left
  proto.fillRect(0, size, size, size);
  proto.fillStyle = color1; // bottom-right
  proto.fillRect(size, size, size, size);
  var pattern = proto.createPattern(proto.canvas, "repeat");
  pattern.data = proto.canvas.toDataURL();
  return pattern;
};

var op_8x8 = createInterlace(8, "#FFF", "#eee");
```


CanvasRenderingContext2D.clearRect() - APIs da Web

CanvasRenderingContext2D.clearRect()
====================================

O método **`CanvasRenderingContext2D.clearRect()`** da API Canvas 2D limpa todos os pixels de um retângulo definido na posição *(x, y)* e tamanho (*width* (largura), *height* (altura)) para uma cor preta transparente, apagando algum conteúdo anterior.

Sintaxe
-------
```

void ctx.clearRect(x, y, width, height);
```

### Parâmetros

`x`

O valor da coordenada x para o ponto inicial do retângulo.

`y`

O valor da coordenada y para o ponto inicial do retângulo.

`width`

A largura do retângulo.

`height`

A altura do retângulo.

Notas de uso
------------

Um problema comum com `clearRect` que pode acontecer, é que pode não funcionar corretamente, caso não seja usada alguma propriedade de *path*. Não esqueça de usar `beginPath()` antes de começar um novo frame depois de chamar `clearRect`.

Exemplos
--------

### Usando o método `clearRect`

Isto é só um simples trecho de código que usa o método `clearRect`.

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(200, 20);
ctx.lineTo(120, 120);
ctx.closePath(); // draws last line of the triangle
ctx.stroke();

ctx.clearRect(10, 10, 100, 100);

// clear the whole canvas
// ctx.clearRect(0, 0, canvas.width, canvas.height);
```

Edite o código abaixo e veja as alterações instantâneas no canvas:
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code" style="height:140px;">
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(200,20);
ctx.lineTo(120,120);
ctx.closePath(); // draws last line of the triangle
ctx.stroke();

ctx.clearRect(10, 10, 100, 100);</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # dom-context-2d-clearrect-dev |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* A definição da interface `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.fillRect()`
* `CanvasRenderingContext2D.strokeRect()`


CanvasRenderingContext2D.stroke() - APIs da Web

CanvasRenderingContext2D.stroke()
=================================

O método **`CanvasRenderingContext2D.stroke()`** da API Canvas 2D contorna um dado *path* ou o *path* atual com o estilo atual de traçado usando uma regra de controle diferente de zero.

Sintaxe
-------
```

void ctx.stroke();
void ctx.stroke(path);
```

### Parâmetros

`path`

Um *path* de `Path2D` para contorno.

Exemplos
--------

### Usando o método `stroke`

Isto é só um simples trecho de código que usa o método `stroke` para contornar um *path*.

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.rect(10, 10, 100, 100);
ctx.stroke();
```

Edite o código abaixo e veja as alterações instantâneas no canvas:
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.rect(10, 10, 100, 100);
ctx.stroke();</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # dom-context-2d-stroke-dev |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* A definição da interface `CanvasRenderingContext2D`.


CanvasRenderingContext2D.lineTo() - APIs da Web

CanvasRenderingContext2D.lineTo()
=================================

O método **`CanvasRenderingContext2D.lineTo()`** da API Canvas 2D conecta o último ponto do sub-caminho (*sub-path*) para as coordenadas `x, y`, através de uma linha (mas na realidade não a desenha).

Sintaxe
-------
```

void ctx.lineTo(x, y);
```

### Parâmetros

`x`

O valor da coordenada x que indica o fim da linha.

`y`

O valor da coordenada y que indica o fim da linha.

Exemplos
--------

### Usando o método `lineTo`

sto é só um simples trecho de código que usa o método `lineTo`. Use o `beginPath()` para indicar o *path* onde será desenhada a linha, mova a caneta (*pen*) com `moveTo()` e use o método `stroke()` para desenhar a linha.

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(100, 100);
ctx.stroke();
```

Edite o código abaixo e veja as alterações instantâneas no canvas:
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(100, 100);
ctx.stroke();</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # dom-context-2d-lineto-dev |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* A definição da interface `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.moveTo()`
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.beginPath() - APIs da Web

CanvasRenderingContext2D.beginPath()
====================================

O método **`CanvasRenderingContext2D.beginPath()`** da API Canvas 2D inicia um novo caminho (*path*), esvaziando a lista de sub-caminhos (*sub-paths*). Use esse método quando você quiser criar um novo *path*.

Sintaxe
-------
```

void ctx.beginPath();
```

Exemplos
--------

### Usando o método `beginPath`

Isto é só um simples trecho de código que usa o método `fillRect`.

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

// Primeiro path
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.moveTo(20, 20);
ctx.lineTo(200, 20);
ctx.stroke();

// Segundo path
ctx.beginPath();
ctx.strokeStyle = "green";
ctx.moveTo(20, 20);
ctx.lineTo(120, 120);
ctx.stroke();
```

Edite o código abaixo e veja as alterações instantâneas no canvas:
```

<canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas>
<div class="playable-buttons">
  <input id="edit" type="button" value="Edit" />
  <input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code" style="height:200px">
// First path
ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.moveTo(20,20);
ctx.lineTo(200,20);
ctx.stroke();

// Second path
ctx.beginPath();
ctx.strokeStyle = 'green';
ctx.moveTo(20,20);
ctx.lineTo(120, 120);
ctx.stroke();</textarea
>
```

```
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var edit = document.getElementById("edit");
var code = textarea.value;

function drawCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawCanvas();
});

edit.addEventListener("click", function () {
  textarea.focus();
});

textarea.addEventListener("input", drawCanvas);
window.addEventListener("load", drawCanvas);
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # dom-context-2d-beginpath-dev |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* A definição da interface `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.closePath()`


Como criar uma árvore DOM - APIs da Web

Como criar uma árvore DOM
=========================

Esta página descreve como usar a API DOM Core em JavaScript para criar e modificar objetos DOM. Aplica-se a todos os aplicativos baseados em Gecko (como Firefox), tanto em código privilegiado (extensões) quanto não privilegiado (páginas da web).

### Criando dinamicamente uma árvore DOM

Considere o seguinte documento XML:

```xml
<?xml version="1.0"?>
<people>
  <person first-name="eric" middle-initial="H" last-name="jung">
    <address street="321 south st" city="denver" state="co" country="usa"/>
    <address street="123 main st" city="arlington" state="ma" country="usa"/>
  </person>

  <person first-name="jed" last-name="brown">
    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
    <address street="123 west st" city="seattle" state="wa" country="usa"/>
    <address street="321 south avenue" city="denver" state="co" country="usa"/>
  </person>
</people>
```

A API W3C DOM, suportada pela Mozilla, pode ser usada para criar uma representação na memória deste documento da seguinte forma:

```js
const doc = document.implementation.createDocument("", "", null);
const peopleElem = doc.createElement("people");

const personElem1 = doc.createElement("person");
personElem1.setAttribute("first-name", "eric");
personElem1.setAttribute("middle-initial", "h");
personElem1.setAttribute("last-name", "jung");

const addressElem1 = doc.createElement("address");
addressElem1.setAttribute("street", "321 south st");
addressElem1.setAttribute("city", "denver");
addressElem1.setAttribute("state", "co");
addressElem1.setAttribute("country", "usa");
personElem1.appendChild(addressElem1);

const addressElem2 = doc.createElement("address");
addressElem2.setAttribute("street", "123 main st");
addressElem2.setAttribute("city", "arlington");
addressElem2.setAttribute("state", "ma");
addressElem2.setAttribute("country", "usa");
personElem1.appendChild(addressElem2);

const personElem2 = doc.createElement("person");
personElem2.setAttribute("first-name", "jed");
personElem2.setAttribute("last-name", "brown");

const addressElem3 = doc.createElement("address");
addressElem3.setAttribute("street", "321 north st");
addressElem3.setAttribute("city", "atlanta");
addressElem3.setAttribute("state", "ga");
addressElem3.setAttribute("country", "usa");
personElem2.appendChild(addressElem3);

const addressElem4 = doc.createElement("address");
addressElem4.setAttribute("street", "123 west st");
addressElem4.setAttribute("city", "seattle");
addressElem4.setAttribute("state", "wa");
addressElem4.setAttribute("country", "usa");
personElem2.appendChild(addressElem4);

const addressElem5 = doc.createElement("address");
addressElem5.setAttribute("street", "321 south avenue");
addressElem5.setAttribute("city", "denver");
addressElem5.setAttribute("state", "co");
addressElem5.setAttribute("country", "usa");
personElem2.appendChild(addressElem5);

peopleElem.appendChild(personElem1);
peopleElem.appendChild(personElem2);
doc.appendChild(peopleElem);
```

Veja também o capítulo DOM do Tutorial XUL.

Você pode automatizar a criação de uma árvore DOM usando um algoritmo reverso JXON em associação com a seguinte representação JSON:

```json
{
  "people": {
    "person": [
      {
        "address": [
          {
            "@street": "321 south st",
            "@city": "denver",
            "@state": "co",
            "@country": "usa"
          },
          {
            "@street": "123 main st",
            "@city": "arlington",
            "@state": "ma",
            "@country": "usa"
          }
        ],
        "@first-name": "eric",
        "@middle-initial": "H",
        "@last-name": "jung"
      },
      {
        "address": [
          {
            "@street": "321 north st",
            "@city": "atlanta",
            "@state": "ga",
            "@country": "usa"
          },
          {
            "@street": "123 west st",
            "@city": "seattle",
            "@state": "wa",
            "@country": "usa"
          },
          {
            "@street": "321 south avenue",
            "@city": "denver",
            "@state": "co",
            "@country": "usa"
          }
        ],
        "@first-name": "jed",
        "@last-name": "brown"
      }
    ]
  }
}
```

### E daí?

As árvores DOM podem ser consultadas usando expressões XPath (en-US), convertidas em strings ou gravadas em arquivos locais ou remotos usando [XMLSerializer](/pt-BR/docs/Web/ Guide/Parsing\_and\_serializing\_XML) (sem ter que primeiro converter para uma string), POSTed to a web server (via `XMLHttpRequest`), transformado usando [XSLT](/ pt-BR/docs/Web/XSLT), XLink (en-US), convertido em um objeto JavaScript por meio de um algoritmo JXON, etc .

Você pode usar árvores DOM para modelar dados que não são adequados para RDF (ou talvez você simplesmente não goste de RDF). Outra aplicação é que, como XUL é XML, a interface do usuário do seu aplicativo pode ser dinamicamente manipulada, baixada, carregada, salva, carregada, convertida ou transformada com bastante facilidade.

Veja também
-----------

* XML (en-US)
* JXON
* XPath (en-US)
* Parsing and serializing XML (en-US)
* XMLHttpRequest


Exemplo de navegação Ajax - APIs da Web

Exemplo de navegação Ajax
=========================

Esse é um exemplo de um web site em AJAX web site composto por apenas três páginas (*first\_page.php*, *second\_page.php* e *third\_page.php*). Para ver como funciona, crie os arquivos a seguir (ou *git clone* https://github.com/giabao/mdn-ajax-nav-example.git ):

**Nota:** Para integrar completamente os elementos `<form>` (en-US) com esse *mecanismo*, porfavor dê uma olhada no parágrafo Enviando formulários e enviando arquivos.

**first\_page.php**:

```php
<?php
 $page\_title = "Primeira página";

 $as\_json = false;
 if (isset($\_GET["view\_as"]) && $\_GET["view\_as"] == "json") {
 $as\_json = true;
 ob\_start();
 } else {
?>
<!doctype html>
<html>
<head>
<?php
 include "include/header.php";
 echo "<title>" . $page\_title . "</title>";
?>
</head>

<body>

<?php include "include/before\_content.php"; ?>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>first_page.php</strong>.</p>

<div id="ajax-content">
<?php } ?>

    <p>Esse é o conteúdo de <strong>first_page.php</strong>.</p>

<?php
 if ($as\_json) {
 echo json\_encode(array("page" => $page\_title, "content" => ob\_get\_clean()));
 } else {
?>
</div>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>first_page.php</strong>.</p>

<?php
 include "include/after\_content.php";
 echo "</body>\n</html>";
 }
?>
```

**second\_page.php**:

```php
<?php
 $page\_title = "Segunda página";

 $as\_json = false;
 if (isset($\_GET["view\_as"]) && $\_GET["view\_as"] == "json") {
 $as\_json = true;
 ob\_start();
 } else {
?>
<!doctype html>
<html>
<head>
<?php
 include "include/header.php";
 echo "<title>" . $page\_title . "</title>";
?>
</head>

<body>

<?php include "include/before\_content.php"; ?>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>second_page.php</strong>.</p>

<div id="ajax-content">
<?php } ?>

    <p>Esse é o conteúdo de <strong>second_page.php</strong>.</p>

<?php
 if ($as\_json) {
 echo json\_encode(array("page" => $page\_title, "content" => ob\_get\_clean()));
 } else {
?>
</div>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>second_page.php</strong>.</p>

<?php
 include "include/after\_content.php";
 echo "</body>\n</html>";
 }
?>
```

**third\_page.php**:

```php
<?php
 $page\_title = "Terceira página";
 $page\_content = "<p>Esse é o conteúdo de <strong>third\_page.php</strong>. This content is stored into a php variable.</p>";

 if (isset($\_GET["view\_as"]) && $\_GET["view\_as"] == "json") {
 echo json\_encode(array("page" => $page\_title, "content" => $page\_content));
 } else {
?>
<!doctype html>
<html>
<head>
<?php
 include "include/header.php";
 echo "<title>" . $page\_title . "</title>";
?>
</head>

<body>

<?php include "include/before\_content.php"; ?>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>third_page.php</strong>.</p>

<div id="ajax-content">
<?php echo $page\_content; ?>
</div>

<p>Esse parágrafo só é mostrado quando a navegação começa em <strong>third_page.php</strong>.</p>

<?php
 include "include/after\_content.php";
 echo "</body>\n</html>";
 }
?>
```

**css/style.css**:

```css
#ajax-loader {
  position: fixed;
  display: table;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

#ajax-loader > div {
  display: table-cell;
  width: 100%;
  height: 100%;
  vertical-align: middle;
  text-align: center;
  background-color: #000000;
  opacity: 0.65;
}
```

**include/after\_content.php**:

```php
<p>Esse é o rodapé. Ele é compartilhado entre todas as páginas ajax.</p>
```

**include/before\_content.php**:

```php
<p>
[ <a class="ajax-nav" href="first\_page.php">Primeiro exemplo</a>
| <a class="ajax-nav" href="second\_page.php">Segundo exemplo</a>
| <a class="ajax-nav" href="third\_page.php">Terceiro exemplo</a>
| <a class="ajax-nav" href="unexisting.php">Página inexistente</a> ]
</p>
```

**include/header.php**:

```php
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/ajax\_nav.js"></script>
<link rel="stylesheet" href="css/style.css" />
```

**js/ajax\_nav.js**:

(antes de implementar em um ambiente de trabalho, **porfavor leia a nota sobre a compatibilidade de declaração de const**)

```js
"use strict";

const ajaxRequest = new (function () {
  function closeReq() {
    oLoadingBox.parentNode && document.body.removeChild(oLoadingBox);
    bIsLoading = false;
  }

  function abortReq() {
    if (!bIsLoading) {
      return;
    }
    oReq.abort();
    closeReq();
  }

  function ajaxError() {
    alert("Unknown error.");
  }

  function ajaxLoad() {
    var vMsg,
      nStatus = this.status;
    switch (nStatus) {
      case 200:
        vMsg = JSON.parse(this.responseText);
        document.title = oPageInfo.title = vMsg.page;
        document.getElementById(sTargetId).innerHTML = vMsg.content;
        if (bUpdateURL) {
          history.pushState(oPageInfo, oPageInfo.title, oPageInfo.url);
          bUpdateURL = false;
        }
        break;
      default:
        vMsg = nStatus + ": " + (oHTTPStatus[nStatus] || "Unknown");
        switch (Math.floor(nStatus / 100)) {
          /\*
 case 1:
 // Informational 1xx
 console.log("Information code " + vMsg);
 break;
 case 2:
 // Successful 2xx
 console.log("Successful code " + vMsg);
 break;
 case 3:
 // Redirection 3xx
 console.log("Redirection code " + vMsg);
 break;
 \*/
          case 4:
            /\* Client Error 4xx \*/
            alert("Client Error #" + vMsg);
            break;
          case 5:
            /\* Server Error 5xx \*/
            alert("Server Error #" + vMsg);
            break;
          default:
            /\* Unknown status \*/
            ajaxError();
        }
    }
    closeReq();
  }

  function filterURL(sURL, sViewMode) {
    return (
      sURL.replace(rSearch, "") +
      (
        "?" +
        sURL
          .replace(rHost, "&")
          .replace(rView, sViewMode ? "&" + sViewKey + "=" + sViewMode : "")
          .slice(1)
      ).replace(rEndQstMark, "")
    );
  }

  function getPage(sPage) {
    if (bIsLoading) {
      return;
    }
    oReq = new XMLHttpRequest();
    bIsLoading = true;
    oReq.onload = ajaxLoad;
    oReq.onerror = ajaxError;
    if (sPage) {
      oPageInfo.url = filterURL(sPage, null);
    }
    oReq.open("get", filterURL(oPageInfo.url, "json"), true);
    oReq.send();
    oLoadingBox.parentNode || document.body.appendChild(oLoadingBox);
  }

  function requestPage(sURL) {
    if (history.pushState) {
      bUpdateURL = true;
      getPage(sURL);
    } else {
      /\* Ajax navigation is not supported \*/
      location.assign(sURL);
    }
  }

  function processLink() {
    if (this.className === sAjaxClass) {
      requestPage(this.href);
      return false;
    }
    return true;
  }

  function init() {
    oPageInfo.title = document.title;
    history.replaceState(oPageInfo, oPageInfo.title, oPageInfo.url);
    for (
      var oLink, nIdx = 0, nLen = document.links.length;
      nIdx < nLen;
      document.links[nIdx++].onclick = processLink
    );
  }

  const /\* customizable constants \*/
    sTargetId = "ajax-content",
    sViewKey = "view\_as",
    sAjaxClass = "ajax-nav",
    /\* not customizable constants \*/
    rSearch = /\?.\*$/,
    rHost = /^[^\?]\*\?\*&\*/,
    rView = new RegExp("&" + sViewKey + "\\=[^&]\*|&\*$", "i"),
    rEndQstMark = /\?$/,
    oLoadingBox = document.createElement("div"),
    oCover = document.createElement("div"),
    oLoadingImg = new Image(),
    oPageInfo = {
      title: null,
      url: location.href,
    },
    oHTTPStatus =
      /\* http://www.iana.org/assignments/http-status-codes/http-status-codes.xml \*/ {
        100: "Continue",
        101: "Switching Protocols",
        102: "Processing",
        200: "OK",
        201: "Created",
        202: "Accepted",
        203: "Non-Authoritative Information",
        204: "No Content",
        205: "Reset Content",
        206: "Partial Content",
        207: "Multi-Status",
        208: "Already Reported",
        226: "IM Used",
        300: "Multiple Choices",
        301: "Moved Permanently",
        302: "Found",
        303: "See Other",
        304: "Not Modified",
        305: "Use Proxy",
        306: "Reserved",
        307: "Temporary Redirect",
        308: "Permanent Redirect",
        400: "Bad Request",
        401: "Unauthorized",
        402: "Payment Required",
        403: "Forbidden",
        404: "Not Found",
        405: "Method Not Allowed",
        406: "Not Acceptable",
        407: "Proxy Authentication Required",
        408: "Request Timeout",
        409: "Conflict",
        410: "Gone",
        411: "Length Required",
        412: "Precondition Failed",
        413: "Request Entity Too Large",
        414: "Request-URI Too Long",
        415: "Unsupported Media Type",
        416: "Requested Range Not Satisfiable",
        417: "Expectation Failed",
        422: "Unprocessable Entity",
        423: "Locked",
        424: "Failed Dependency",
        425: "Unassigned",
        426: "Upgrade Required",
        427: "Unassigned",
        428: "Precondition Required",
        429: "Too Many Requests",
        430: "Unassigned",
        431: "Request Header Fields Too Large",
        500: "Internal Server Error",
        501: "Not Implemented",
        502: "Bad Gateway",
        503: "Service Unavailable",
        504: "Gateway Timeout",
        505: "HTTP Version Not Supported",
        506: "Variant Also Negotiates (Experimental)",
        507: "Insufficient Storage",
        508: "Loop Detected",
        509: "Unassigned",
        510: "Not Extended",
        511: "Network Authentication Required",
      };

  var oReq,
    bIsLoading = false,
    bUpdateURL = false;

  oLoadingBox.id = "ajax-loader";
  oCover.onclick = abortReq;
  oLoadingImg.src =
    "data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==";
  oCover.appendChild(oLoadingImg);
  oLoadingBox.appendChild(oCover);

  onpopstate = function (oEvent) {
    bUpdateURL = false;
    oPageInfo.title = oEvent.state.title;
    oPageInfo.url = oEvent.state.url;
    getPage();
  };

  window.addEventListener
    ? addEventListener("load", init, false)
    : window.attachEvent
      ? attachEvent("onload", init)
      : (onload = init);

  // Public methods

  this.open = requestPage;
  this.stop = abortReq;
  this.rebuildLinks = init;
})();
```

**Nota:** A atual implementação de `const` (declaração de constante) **não é parte do ECMAScript 5**. É suportada no Firefox e no Chrome (V8) e parcialmente suportada no Opera 9+ e no Safari. **Ela não é suportada nas versões do Internet Explorer 6 ao 9, ou na versão *preview* do Internet Explorer 10**. `const` será definida no ECMAScript 6, mas com semânticas diferentes. Similarmente ao que acontece com variáveis definidas como `let`, constantes declaradas com `const` serão *block-scoped*, limitando seu escopo no bloco. **Nós só usamos isso com propósito didático. Se você quer total compatibilidade com os navegadores, substitua todas as declarações `const` por declarações `var`.**

Para mais informações, veja: Manipulando o histórico do navegador (en-US).

Veja também
-----------

* `window.history`
* `window.onpopstate` (en-US)


Uma simples amostra de RTCDataChannel - APIs da Web

Uma simples amostra de RTCDataChannel
=====================================

A interface `RTCDataChannel` é um recurso da WebRTC API que permite abrir um canal entre dois pares sobre os quais você pode enviar e receber dados arbitrários. A API é intencionalmente semelhante à WebSocket API (en-US), de modo que o mesmo modelo de programação pode ser usado para ambos.

Neste exemplo, abriremos um `RTCDataChannel` para realizar a conexão entre dois elementos na mesma página. Embora seja obviamente um cenário artificial, é útil para demonstrar o fluxo de conexão entre dois pares. Vamos cobrir a mecânica necessária para conectar, transmitir e receber dados, mas vamos deixar para outro exemplo os detalhes sobre como localizar e se conectar a um computador remoto.

O HTML
------

Primeiro, vamos dar uma olhada rápida no HTML que é necessário. Não há nada incrivelmente complicado aqui. Primeiro, temos um par de botões para estabelecer e fechar a conexão:

```html
<button id="connectButton" name="connectButton" class="buttonleft">
  Conectar
</button>
<button
 id="disconnectButton"
 name="disconnectButton"
 class="buttonright"
 disabled>
  Desconectar
</button>
```

Depois, há uma caixa que contém o campo de *input* no qual o usuário pode digitar uma mensagem para transmitir, com um botão para enviar o texto digitado. Este `<div>` será o primeiro ponto (peer) no canal.

```html
<div class="messagebox">
  <label for="message"
 >Insira a mensagem:
    <input
 type="text"
 name="message"
 id="message"
 placeholder="Texto da mensagem"
 inputmode="latin"
 size="60"
 maxlength="120"
 disabled />
  </label>
  <button id="sendButton" name="sendButton" class="buttonright" disabled>
    Enviar
  </button>
</div>
```

Finalmente, há uma pequena caixa na qual vamos inserir as mensagens. Este bloco `<div>` será o segundo ponto do par (peer).

```html
<div class="messagebox" id="receivebox">
  <p>Mensagens recebidas:</p>
</div>
```

O código JavaScript
-------------------

Como você pode simplesmente ver o próprio código no GitHub, abaixo, analisaremos as partes do código que fazem o trabalho pesado.

A WebRTC API faz um intenso uso de `Promise`s. Que tornam muito fácil encadear as etapas do processo de conexão; Se você ainda não leu sobre esta funcionalidade do ECMAScript 2015, você deveria ler sobre eles. Da mesma forma, este exemplo usa arrow functions para simplificar a sintaxe.

### Começando

Quando o script é executado, configuramos um `load (en-US)` ouvinte de eventos (event listener), De modo que, uma vez que a página esteja totalmente carregada, nossa função `startup()` seja chamada.

```js
function startup() {
  connectButton = document.getElementById("connectButton");
  disconnectButton = document.getElementById("disconnectButton");
  sendButton = document.getElementById("sendButton");
  messageInputBox = document.getElementById("message");
  receiveBox = document.getElementById("receivebox");

  // Define os ouvintes de eventos para os elementos da interface do usuário

  connectButton.addEventListener("click", connectPeers, false);
  disconnectButton.addEventListener("click", disconnectPeers, false);
  sendButton.addEventListener("click", sendMessage, false);
}
```

Isso é bastante direto. Pegamos referências de todos os elementos da página que precisaremos acessar e, em seguida, configuramos `event listeners` nos três botões.

### Estabelecendo uma conexão

Quando o usuário clica no botão "Conectar", o método `connectPeers()` é chamado. Para que fique mais claro, iremos quebrar o código em mais partes, e analisar um pouco de cada vez.

**Nota:** Mesmo que ambas as extremidades da nossa conexão estejam na mesma página, vamos nos referir ao ponto que inicia a conexão como "local", e ao outro como sendo o "remoto".

#### Configurando o ponto local (local peer)

```js
localConnection = new RTCPeerConnection();

sendChannel = localConnection.createDataChannel("sendChannel");
sendChannel.onopen = handleSendChannelStatusChange;
sendChannel.onclose = handleSendChannelStatusChange;
```

O primeiro passo é criar o ponto "local" da conexão. Este é o ponto que enviará o pedido de conexão. O próximo passo é criar o `RTCDataChannel` chamando `RTCPeerConnection.createDataChannel()` (en-US) e configurando ouvintes de eventos (event listeners) para monitorar o canal, e para que possamos saber quando ele for aberto e fechado (isto é, quando o canal está conectado ou desconectado dentro dessa conexão entre pares (peer connection)).

É importante ter em mente que cada extremidade do canal tem seu próprio objeto `RTCDataChannel` .

#### Configurando o ponto remoto (remote peer)

```js
remoteConnection = new RTCPeerConnection();
remoteConnection.ondatachannel = receiveChannelCallback;
```

O ponto remoto está configurado de forma semelhante, exceto que não precisamos nós mesmos criar explicitamente um `RTCDataChannel` , uma vez que vamos ser conectados através do canal estabelecido acima. Em vez disso, criamos um `datachannel` manipulador de eventos (event handler); Isso será chamado quando o canal de dados (data channel) for aberto; Este manipulador (handler) receberá um objeto `RTCDataChannel`; você verá isso abaixo.

#### Configurando ICE candidates

O próximo passo é configurar cada conexão com os ouvintes do ICE que serão chamados quando houver um novo candidato ICE para comunicar com o outro lado.

**Nota:** Em um cenário do mundo real em que os dois pares não estão sendo executados no mesmo contexto, o processo é um pouco mais complexo; Cada lado fornece, um de cada vez, um sugestão sobre como conectar (por exemplo, UDP, UDP com um relay, TCP, etc.) chamando `RTCPeerConnection.addIceCandidate()` (en-US), e eles vão de um lado para outro até chegarem a um acordo. Mas aqui, acabamos de aceitar a primeira oferta de cada lado, uma vez que não existe uma rede real envolvida.

```js
localConnection.onicecandidate = (e) =>
  !e.candidate ||
  remoteConnection.addIceCandidate(e.candidate).catch(handleAddCandidateError);

remoteConnection.onicecandidate = (e) =>
  !e.candidate ||
  localConnection.addIceCandidate(e.candidate).catch(handleAddCandidateError);
```

Configuramos cada `RTCPeerConnection` (en-US) para ter um manipulador de eventos (event handler) para o evento `icecandidate` .

#### Iniciando a tentativa de conexão

A última coisa que precisamos fazer para começar a conectar nossos pares é criar uma oferta de conexão.

```js
localConnection
  .createOffer()
  .then((offer) => localConnection.setLocalDescription(offer))
  .then(() =>
    remoteConnection.setRemoteDescription(localConnection.localDescription),
  )
  .then(() => remoteConnection.createAnswer())
  .then((answer) => remoteConnection.setLocalDescription(answer))
  .then(() =>
    localConnection.setRemoteDescription(remoteConnection.localDescription),
  )
  .catch(handleCreateDescriptionError);
```

Vamos passar por isto linha por linha e decifrar o que significa.

1. Primeiro chamamos `RTCPeerConnection.createOffer()` (en-US) método para criar um resumo SDP (Session Description Protocol) descrevendo a conexão que queremos fazer. Este método aceita, opcionalmente, um objeto com restrições a serem suportadas pela conexão para atender às suas necessidades, como no caso da conexão precisar suportar áudio, vídeo ou ambos. Em nosso exemplo simples, não temos restrições.
2. Se a oferta for criada com sucesso, passamos o resumo junto ao método de conexões locais `RTCPeerConnection.setLocalDescription()` (en-US) . Isso configura o ponto local da conexão.
3. O próximo passo é conectar o ponto local ao remoto comunicando ao ponto remoto sobre ele. Isso é feito chamando `remoteConnection.``RTCPeerConnection.setRemoteDescription()` (en-US). Agora o `remoteConnection` conhece a conexão que está sendo construída.
4. Isso significa que é hora do ponto remoto responder. Ele faz isso chamando o método `createAnswer()` (en-US) . Isso gera um resumo de SDP que descreve a conexão que o ponto remoto está disposto e capaz de estabelecer. Essa configuração está em algum lugar na união das opções que ambos os pares podem suportar.
5. Uma vez que a resposta foi criada, ela é passada para o *remoteConnection* chamando `RTCPeerConnection.setLocalDescription()` (en-US). Isso estabelece o ponto remoto da conexão (que, para o ponto remoto, é o ponto local. Isso pode parecer confuso, mas você irá se acostumar com isso.
6. Finalmente, a descrição local das conexões remotas está configurada para se referir ao ponto remoto, chamando localConnection's `RTCPeerConnection.setRemoteDescription()` (en-US).
7. O `catch()` chama uma rotina que lida com os erros que ocorrem.

**Nota:** Mais uma vez, esse processo não é uma implementação do mundo real; No uso normal, há dois pedaços de código executados em duas máquinas, interagindo e negociando a conexão.

#### Manipulação da conexão de pares bem sucedida

Como cada lado da conexão peer-to-peer é conectado com sucesso, o evento correspondente `RTCPeerConnection` (en-US)'s `icecandidate` é disparado. Esses manipuladores podem fazer o que for necessário, mas, neste exemplo, tudo o que precisamos fazer é atualizar a interface do usuário:

```js
function handleLocalAddCandidateSuccess() {
  connectButton.disabled = true;
}

function handleRemoteAddCandidateSuccess() {
  disconnectButton.disabled = false;
}
```

A única coisa que fazemos aqui é desativar o botão "Conectar" quando o ponto local estiver conectado e ativar o botão "Desconectar" quando o ponto remoto se conectar.

#### Conectando o canal de dados

Uma vez que o `RTCPeerConnection` (en-US) é aberto, o evento `datachannel` é enviado para o ponto remoto para completar o processo de abertura do canal de dados; Isso invoca nosso método `receiveChannelCallback()`, que se parece com isso:

```js
function receiveChannelCallback(event) {
  receiveChannel = event.channel;
  receiveChannel.onmessage = handleReceiveMessage;
  receiveChannel.onopen = handleReceiveChannelStatusChange;
  receiveChannel.onclose = handleReceiveChannelStatusChange;
}
```

O evento`datachannel` inclui, em sua propriedade de canal, uma referência a um `RTCDataChannel` Representando o ponto remoto do canal. Isso é salvo, e nós configuramos, no canal, ouvintes de eventos para os eventos que queremos manipular. Uma vez feito isso, nosso método `handleReceiveMessage()` Será chamado cada vez que os dados são recebidos pelo ponto remoto, e o método `handleReceiveChannelStatusChange()` será chamado sempre que mudar o estado da conexão do canal, para que possamos reagir quando o canal estiver totalmente aberto e quando ele for fechado.

### Lidando com as mudanças de status do canal

Ambos nossos pontos locais e remotos usam um único método para lidar com eventos que indicam alguma alteração no status da conexão do canal.

Quando o ponto local experimenta um evento aberto ou fechado, o método`handleSendChannelStatusChange()` é chamado:

```js
function handleSendChannelStatusChange(event) {
  if (sendChannel) {
    var state = sendChannel.readyState;

    if (state === "open") {
      messageInputBox.disabled = false;
      messageInputBox.focus();
      sendButton.disabled = false;
      disconnectButton.disabled = false;
      connectButton.disabled = true;
    } else {
      messageInputBox.disabled = true;
      sendButton.disabled = true;
      connectButton.disabled = false;
      disconnectButton.disabled = true;
    }
  }
}
```

Se o estado do canal mudou para "open", isso indica que terminamos de estabelecer o link entre os dois pares. A interface do usuário é atualizada de forma correspondente: ativando o elemento de input de texto para a mensagem a ser enviada, focando este elemento de input para que o usuário comece imediatamente a digitar, habilitando os botões "Enviar" e "Desconectar", que são agora utilizáveis, E desativando o botão "Conectar", uma vez que não é necessário quando a conexão está aberta.

Se o estado do canal mudou para "closed", ocorre o conjunto oposto de ações: a caixa de entrada de texto e o botão "Enviar" estão desativados, o botão "Conectar" está habilitado para que o usuário possa abrir uma nova conexão se desejar, e o botão "Desconectar" está desativado, uma vez que não é útil quando não existe conexão.

Nosso exemplo de par remoto, por outro lado, ignora os eventos de alteração de status, exceto para registrar o evento no console:

```js
function handleReceiveChannelStatusChange(event) {
  if (receiveChannel) {
    console.log(
      "Receive channel's status has changed to " + receiveChannel.readyState,
    );
  }
}
```

O método `handleReceiveChannelStatusChange()` recebe como parâmetro de entrada o evento que ocorreu; Este será um `RTCDataChannelEvent` (en-US).

### Enviando mensagens

Quando o usuário pressiona o botão "Enviar", o método sendMessage() que estabelecemos como o manipulador para o evento do botão `click (en-US)` é chamado. Esse método é bastante simples:

```js
function sendMessage() {
  var message = messageInputBox.value;
  sendChannel.send(message);

  messageInputBox.value = "";
  messageInputBox.focus();
}
```

Primeiro, o texto da mensagem é obtido dos atributos do elemento de *input* `value` . Isso é enviado para o ponto remoto, ligando para `sendChannel.send()` (en-US). E está tudo aí! O resto deste método é apenas um pouco de açúcar para experiência do usuário - a caixa de entrada é esvaziada e re-focada para que o usuário comece imediatamente a digitar outra mensagem.

### Recebendo mensagens

Quando ocorre um evento de "mensagem" no canal remoto, nosso método `handleReceiveMessage()` é chamado como o manipulador de eventos.

```js
function handleReceiveMessage(event) {
  var el = document.createElement("p");
  var txtNode = document.createTextNode(event.data);

  el.appendChild(txtNode);
  receiveBox.appendChild(el);
}
```

Este método simplesmente executa alguns injeções básicas DOM ; cria um novo `<p>` (paragraph) elemento, então cria um novo nó `Text` (en-US) contendo o texto da mensagem, que é recebido na propriedade de dados do evento. Este nó de texto é anexado como um filho do novo elemento, que é então inserido no bloco *receiveBox*, fazendo com que ele desenhe na janela do navegador.

### Desconectando os pares (peers)

Quando o usuário clica no botão "Desconectar", o método `disconnectPeers()` previamente configurado como o manipulador desse botão é chamado.

```js
function disconnectPeers() {
  // Close the RTCDataChannels if they're open.

  sendChannel.close();
  receiveChannel.close();

  // Close the RTCPeerConnections

  localConnection.close();
  remoteConnection.close();

  sendChannel = null;
  receiveChannel = null;
  localConnection = null;
  remoteConnection = null;

  // Update user interface elements

  connectButton.disabled = false;
  disconnectButton.disabled = true;
  sendButton.disabled = true;

  messageInputBox.value = "";
  messageInputBox.disabled = true;
}
```

Isso começa por fechar cada par `RTCDataChannel`, então, de forma semelhante, cada um `RTCPeerConnection` (en-US). Então, todas as referências salvas desses objetos são definidas como null para evitar a reutilização acidental, e a interface do usuário é atualizada para refletir o fato de que a conexão foi fechada.

Próximos passos
---------------

Você poderia tentar este exemplo e dar uma olhada no código fonte webrtc-simple-datachannel, disponível no GitHub.


Introdução aos protocolos WebRTC - APIs da Web

Introdução aos protocolos WebRTC
================================

Este artigo apresenta os protocolos sobre os quais a API WebRTC é construída.

ICE
---

Interactive Connectivity Establishment (ICE) é a estrutura que permite seu navegador web se conectar com outras pessoas. Existem muitas razões pelas quais uma conexão direta do Ponto A para o Ponto B simplesmente não funciona. Ele precisa ignorar firewalls que impediriam a abertura de conexões, fornecer um endereço exclusivo, como na maioria das situações, caso seu dispositivo não tiver um endereço IP público e retransmitir dados por meio de um servidor ou se seu roteador não permitir a conexão direta com seus pares . O ICE usa servidores STUN e / ou TURN para fazer isso, conforme descrito abaixo.

STUN
----

Session Traversal Utilities for **NAT** (STU**N**) (sigla dentro de uma sigla) é um protocolo para descobrir seu endereço público e determinar quaisquer restrições em seu roteador que poderiam impedir uma conexão direta com um par.

O cliente enviará uma solicitação a um servidor STUN na Internet que responderá com o endereço público do cliente e se o cliente está ou não acessível por meio do NAT do roteador.

![An interaction between two users of a WebRTC application involving a STUN server.](/pt-BR/docs/Web/API/WebRTC_API/Protocols/webrtc-stun.png)

NAT
---

Network Address Translation (NAT) é usado para dar ao seu dispositivo um endereço IP público. Um roteador terá um endereço IP público e cada dispositivo conectado ao roteador terá um endereço IP privado. As solicitações serão traduzidas do IP privado do dispositivo para o IP público do roteador com uma porta exclusiva. Dessa forma, você não precisa de um IP público exclusivo para cada dispositivo, mas ainda pode ser descoberto na Internet.

Alguns roteadores terão restrições sobre quem pode se conectar a dispositivos na rede. Isso pode significar que, embora tenhamos o endereço IP público encontrado pelo servidor STUN, ninguém pode criar uma conexão. Nesta situação, precisamos voltar para TURN.

TURN
----

Alguns roteadores que usam NAT empregam uma restrição chamada 'Symmetric NAT' (*NAT simétrico*). Isso significa que o roteador só aceitará conexões de pares aos quais você já se conectou.

Traversal Using Relays around NAT (TURN) destina-se a contornar a restrição de NAT simétrico abrindo uma conexão com um servidor TURN para que ele re-transmita toda informação. Você criaria uma conexão com um servidor TURN e avisaria a todos os pares (*peers*) para enviar pacotes para este servidor, que lhe encaminharia. Isso obviamente vem com alguma sobrecarga, então só é usado se não houver outras alternativas.

![An interaction between two users of a WebRTC application involving STUN and TURN servers.](/pt-BR/docs/Web/API/WebRTC_API/Protocols/webrtc-turn.png)

SDP
---

Session Description Protocol (SDP) é um padrão para descrever o conteúdo multimídia da conexão, como resolução, formatos, codecs, criptografia, etc., para que os dois pontos possam se entender uma vez que os dados estejam sendo transferidos. Em essência, são os metadados que descrevem o conteúdo e não o conteúdo da mídia em si.

Tecnicamente, então, SDP não é realmente um protocolo, mas um formato de dados usado para descrever a conexão que compartilha mídia entre dispositivos.

A documentação do SDP está bem fora do escopo desta documentação; no entanto, existem algumas coisas que vale a pena observar aqui.

### Estrutura

O SDP consiste em uma ou mais linhas de texto UTF-8, cada uma começando com um tipo de um caractere, seguido por um sinal de igual ("="), seguido por um texto estruturado contendo um valor ou descrição, cujo formato depende do tipo. As linhas de texto que começam com uma determinada letra são geralmente chamadas de "letter-lines" (*"linhas de letras"*). Por exemplo, as linhas que fornecem descrições de mídia têm o tipo "m", portanto, essas linhas são chamadas de "linhas m".

### Para mais informações

Para saber mais sobre o SDP, consulte os seguintes recursos úteis:

* Especificação: RFC 4566: SDP: Session Description Protocol
* IANA registry of SDP parameters


ServiceWorkerContainer.register() - APIs da Web

ServiceWorkerContainer.register()
=================================

**Experimental:** **Esta é uma tecnologia experimental (en-US)**
Verifique a tabela de compatibilidade entre Navegadores cuidadosamente antes de usar essa funcionalidade em produção.

O método \*\*`register()`\*\*da interface `ServiceWorkerContainer` (en-US) cria ou atualiza um `ServiceWorkerRegistration` (en-US) passado em `scriptURL`.

Em caso de sucesso, um registro de service worker vincula o URL do script fornecido ao es*copo*, que é usado posteriormente para a navegação correspondente. Você pode chamar esse método incondicionalmente da página controlada. Ou seja, você não precisa primeiro verificar se há um registro ativo.

Há uma frequente confusão em relação ao significado e uso do escopo. Uma vez que um service worker não pode ter um escopo mais amplo do que sua própria localização, use apenas a opção `scope` quando precisar de um escopo mais limitado do que o padrão.

Síntaxe
-------
```

ServiceWorkerContainer.register(scriptURL, options)
  .then(function(ServiceWorkerRegistration) { ... });
```

### Parâmetros

`scriptURL`

A URL do script service worker.

`options` Optional

Um objeto contendo as opções do registro. Atualmente as opções disponíveis são:

* `scope`: Uma `USVString` (en-US) representando uma URL que define o registro do escopo de um service worker's ; ou seja, o alcance das URLs que o service worker pode controlar. É geralmente uma URL relativa. O valor padrão é o URL que você obtém se você resolvesse './' usando a localização da página web como base. Não é, como customa-se acreditar, relativo à localização do service worker. Veja as seções de Exemplos para mais informações sobre como isso funciona.

### Valor retornado

Um `Promise` (en-US) que resolve com um objeto `ServiceWorkerRegistration` (en-US).

Exemplos
--------

Os exemplos descritos escrito aqui deve ser tomado em conjunto para obter um melhor entendimento de como escopos do service workers são aplicados a uma página.

O exemplo a seguir usa o valor padrão de`scope` (ao omití-lo). O service worker neste caso irá controlar`example.com/index.html` bem como páginas abaixo, como `example.com/product/description.html`.

```js
if ("serviceWorker" in navigator) {
  // Registra um service worker hospeadado na raiz do
  // site usando o escopo padrão
  navigator.serviceWorker
    .register("/sw.js")
    .then(function (registration) {
      console.log("Service worker registrado com sucesso:", registration);
    })
    .catch(function (error) {
      console.log("Falha ao Registrar o Service Worker:", error);
    });
} else {
  console.log("Service workers não suportado!");
}
```

O código a seguir, se incluído em uma página na raiz de um site, seria aplicado exatamente às mesmas páginas, como no exemplo acima. Lembre-se de que o escopo, quando incluído, usa a localização da página como base. Alternativamente, se esse código foi incluído em uma página `example.com/product/description.html`, o escopo de`'./'` significa que o escopo que o service worker seria aplicado somente aos recursos de`example.com/product`. Se precisassemos de registrar um service worker em `example.com/product/description.html` aplicado a todoo `example.com`, deixaríamos o escopo acima.

```js
if ("serviceWorker" in navigator) {
  // Registre um service worker hospeado na raiz do
  // site usando um escopo mais restritivo.
  navigator.serviceWorker
    .register("/sw.js", { scope: "./" })
    .then(function (registration) {
      console.log("Service worker registrado com sucesso:", registration);
    })
    .catch(function (error) {
      console.log("Service worker falhou ao registrar:", error);
    });
} else {
  console.log("Service workers não é suportado pelo navegador!.");
}
```

Especificações
--------------

| Specification |
| --- |
| Service Workers # navigator-service-worker-register |

Compatibilidade com navegadores
-------------------------------

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


window.requestAnimationFrame() - APIs da Web

window.requestAnimationFrame()
==============================

 O método **`window.requestAnimationFrame()`** fala para o navegador que deseja-se realizar uma animação e pede que o navegador chame uma função específica para atualizar um quadro de animação antes da próxima repaint (repintura). O método tem como argumento uma callback que deve ser invocado antes da repaint.

>
> \*\*Nota:\*\*A rotina callback deve chamar `requestAnimationFrame()` se quiser animar outro quadro na próxima repaint.
>
>
>

Deve-se chamar esse método sempre que estiver pronto para atualizar a animação na tela. Isso irá requisitar que a função de animação seja chamada antes que o navegador realize a próxima repaint. O número de callbacks é normalmente 60 por segundo, mas geralmente acompanha a taxa de atualização do display na maioria dos navegadores, como recomenda a W3C. A taxa de callbacks é reduzida quando executados em aba de fundo ou em `<iframe>` escondidos para melhorar performance e vida de bateria.

Um único argumento é passado para o método callback, um `DOMHighResTimeStamp` (en-US), que indica o tempo atual no qual callbacks enfileiradas por `requestAnimationFrame` começam a disparar. Múltiplos callbacks em um único quadro, assim, cada um recebe o mesmo carimbo de data/hora . Esse carimbo de data/hora é um número decimal, em milisegundos, mas com precisão mínima de 1ms (1000 µs).

Sintaxe
-------
```

window.requestAnimationFrame(callback);
```

### Parâmetros

`callback`

Parâmetro especificando uma função a ser chamada quando chegar a hora de atualizar a animação para a próxima repaint. O callback possui um único argumento, um `DOMHighResTimeStamp` (en-US), que indica a hora atual (a hora retornada de `Performance.now()` ) para quando `requestAnimationFrame` começar a disparar callbacks.

### Valor de retorno

Um valor inteiro `long`, a id da requisição, que identifica unicamente a entrada na lista de callbacks. Esse é um valor não-zero, mas não deve-se assumir mais nada sobre esse valor. Esse valor pode ser passado para `window.cancelAnimationFrame()` (en-US) para cancelar a requisição da atualização do callback.

Exemplo
-------

```js
var start = null;
var element = document.getElementById("ElementoQueVcQuerAnimar");
element.style.position = "absolute";

function step(timestamp) {
  if (!start) start = timestamp;
  var progress = timestamp - start;
  element.style.left = Math.min(progress / 10, 200) + "px";
  if (progress < 2000) {
    window.requestAnimationFrame(step);
  }
}

window.requestAnimationFrame(step);
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # dom-animationframeprovider-requestanimationframe |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `Window.mozAnimationStartTime` (en-US)
* `Window.cancelAnimationFrame()` (en-US)
* mozRequestAnimationFrame - Post do blog
* requestAnimationFrame for smart animating - Post do blog
* Animating with javascript: from setInterval to requestAnimationFrame - Post do blog
* Using PC Hardware more efficiently in HTML5: New Web Performance APIs, Part 1 - Post do blog
* TestUFO: Test your web browser for requestAnimationFrame() Timing Deviations
* Paul Irish: requestAnimationFrame for Smart Animating
* Paul Irish: requestAnimationFrame API: now with sub-millisecond precision


Event.type - APIs da Web

Event.type
==========

Sumário
-------

Retorna uma string contendo o tipo de evento.

O argumento do evento `EventTarget.addEventListener()` e `EventTarget.removeEventListener()` é caso insensível(case insensitive).

Veja Mozilla event reference (en-US) para obter a lista de tipos de evento disponíveis

Sintaxe
-------
```

event.type
```

Exemplos
--------
```

var string = event.type;
```

```html
<!doctype html>
<html lang="pt-br">
  <head>
    <title>exemplo de tipo</title>

    <script>
 var currEvent = null;

 function getEvtType(evt) {
 currEvent = evt.type;
 document.getElementById("Etype").firstChild.nodeValue = currEvent;
 }
 </script>
  </head>

  <body
 onkeydown="getEvtType(event)"
 onkeyup="getEvtType(event)"
 onmousedown="getEvtType(event)"
 onmouseup="getEvtType(event)">
    <p>
      Pressione uma tecla ou clique com o mouse para obter o tipo de evento.
    </p>
    <p>Tipo de evento: <span id="Etype">-</span></p>
  </body>
</html>
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-type④ |

Compatibilidade com navegadores
-------------------------------

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


Event.isTrusted - APIs da Web

Event.isTrusted
===============

 A propriedade **`isTrusted`** da interface `Event`, exclusiva para leitura, é uma booleana (`Boolean` (en-US)) de valor verdadeiro (`true`) se tal evento é disparado pela ação do usuário. Retorna falso (`false`) caso o acionamento do evento seja ocasionado pelo método `EventTarget.dispatchEvent()` ou tenha sido criado ou modificado por um script.
Sintaxe
-------
```

var eventIsTrusted = event.isTrusted;
```

### Valor

`Boolean` (en-US)Exemplo
-------

```js
if (e.isTrusted) {
  /\* The event is trusted \*/
} else {
  /\* The event is not trusted \*/
}
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-istrusted① |

Compatibilidade com navegadores
-------------------------------

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


Event.stopPropagation() - APIs da Web

Event.stopPropagation()
=======================

Resumo
------

Impede a propagação do evento por seus respectivos listeners.

Sintaxe
-------
```

event.stopPropagation();
```

### Parametros

Nenhum

### Valor retornado

`undefined`.

Exemplo
-------

Veja o exemplo 5: Event Propagation (en-US) no capítulo Eventos para um exemplo mais detalhado desse método e propagação de evento no DOM.

Notas
-----

Veja DOM specification para a explicação do fluxo de eventos. (O DOM Level 3 Events draft possui uma ilustração.)

preventDefault (en-US) é um método de complemento que pode ser usado para previnir a ação padrão do evento que estiver acontecendo.

Especificação
-------------

DOM Level 3 Events: stopPropagation

Compatibilidade com navegadores
-------------------------------

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


Event.target - APIs da Web

Event.target
============

Uma referência ao objeto que enviou o evento. É diferente de `event.currentTarget` quando o manipulador de eventos é chamado durante a fase de borbulhagem ou captura do evento.

Sintaxe
-------
```

theTarget = event.target
```

Exemplo
-------

A propriedade **`event.target`** pode ser usada para implementar a delegação de eventos.

```js
// Assumindo que existe uma variável 'list' contendo uma instância de um elemento ul de HTML.
function hide(e) {
  // A menos que os itens da lista sejam separados por uma margem, e.target deve ser diferente de e.currentTarget
  e.target.style.visibility = "hidden";
}

list.addEventListener("click", hide, false);

// Se algum elemento (elemento <li> ou um link dentro de um elemento <li> por exemplo) for clicado, ele desaparecerá.
// Só requer um único listener para fazer isso.
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-target③ |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* Comparison of Event Targets


Event() - APIs da Web

Event()
=======

O **`Event()`** cria uma nova `Event`.

Sintaxe
-------
```

 event = new Event(typeArg, eventInit);
```

### Valores

*typeArg*

É uma `DOMString` representa o nome do evento.

*eventInit*Optional

É um dicionário `EventInit`, tendo os seguintes campos:

* `"bubbles"`, opcional e false por default, do tipo `Boolean`, indica se o evento é bubbles ou não.
* `"cancelable"`, opcional e false por default, do tipo `Boolean`, indica se o evento pode ser cancelado ou não.

Exemplo
-------

```js
// criar um evento com bubbles true e que não pode ser cancelado

var ev = new Event("look", { bubbles: true, cancelable: false });
document.dispatchEvent(ev);
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-event |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `Event`


Comparativo entre Event Targets - APIs da Web

Comparativo entre Event Targets
===============================

### Event targets

É facil se confundir sobre o tipo de alvo (*target*) que deseja-se examinar ao criar um manipulador de eventos (*event handler*). Este artigo se propõe a esclarecer o uso da propriedade *target*.

Há 5 tipos de *targets* a se considerar:

| Propriedade | Definido em | Objetivo |
| --- | --- | --- |
| event.target | DOM Event Interface |
 O elemento do DOM à esquerda da chamada que disparou este evento, por
 exemplo:

```

*element*.dispatchEvent(*event*)
```

 |
| event.currentTarget | DOM Event Interface |
 O
 `EventTarget`
 do qual o
 `EventListeners`
 está sendo atualmente processado. Logo que a captura e a subida do
 evento ocorre a mudança deste valor.
  |
| event.relatedTarget | DOM MouseEvent Interface | Identifica um alvo secundário para o evento. |
| event.explicitOriginalTarget | Event.webidl |
Non-standard
 Se o evento foi redirecionado por
 alguma outra razão senão o cruzamento de uma fronteira anônima, este
 evento será colocado no alvo antes que o redirecionamento ocorra. por
 exemplo, eventos do mouse são redirecionados à seus elementos pais
 quando acontecem sobre nós de texto ([Firefox bug 185889](https://bugzil.la/185889)), e neste
 caso .target mostrará o nó pai e
 `.explicitOriginalTarget` mostrará o nó texto. Diferente de
 `.originalTarget`, `.explicitOriginalTarget` nunca
 irá conter um conteúdo anônimo.
  |
| event.originalTarget | Event.webidl |
Non-standard
 O alvo original do evento, antes de
 qualquer redirecionamento. Veja
 Anonymous Content#Event\_Flow\_and\_Targeting
 para mais detalhes.
  |

### Uso de `explicitOriginalTarget` e `originalTarget`

TODO: Disponível apensas em navegadores Mozilla-based?

TODO: Adequado apenas para desenvolvedores de extensões?

### Exemplos
```

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Comparison of Event Targets</title>
    <style>
        table {
            border-collapse: collapse;
            height: 150px;
            width: 100%;
        }
        td {
            border: 1px solid #ccc;
            font-weight: bold;
            padding: 5px;
            min-height: 30px;
        }
        .standard {
            background-color: #99ff99;
        }
        .non-standard {
            background-color: #902D37;
        }
    </style>
</head>
<body>
    <table>
    <thead>
        <tr>
            <td class="standard">Original target dispatching the event <small>event.target</small></td>
            <td class="standard">Target who's event listener is being processed <small>event.currentTarget</small></td>
            <td class="standard">Identify other element (if any) involved in the event <small>event.relatedTarget</small></td>
            <td class="non-standard">If there was a retargetting of the event for some reason <small> event.explicitOriginalTarget</small> contains the target before retargetting (never contains anonymous targets)</td>
            <td class="non-standard">If there was a retargetting of the event for some reason <small> event.originalTarget</small> contains the target before retargetting (may contain anonymous targets)</td>
        </tr>
    </thead>
    <tr>
        <td id="target"></td>
        <td id="currentTarget"></td>
        <td id="relatedTarget"></td>
        <td id="explicitOriginalTarget"></td>
        <td id="originalTarget"></td>
    </tr>
</table>
<p>Clicking on the text will show the difference between explicitOriginalTarget, originalTarget and target</p>
<script>
    function handleClicks(e) {
        document.getElementById('target').innerHTML = e.target;
        document.getElementById('currentTarget').innerHTML = e.currentTarget;
        document.getElementById('relatedTarget').innerHTML = e.relatedTarget;
        document.getElementById('explicitOriginalTarget').innerHTML = e.explicitOriginalTarget;
        document.getElementById('originalTarget').innerHTML = e.originalTarget;
    }

    function handleMouseover(e) {
        document.getElementById('target').innerHTML = e.target;
        document.getElementById('relatedTarget').innerHTML = e.relatedTarget;
    }

    document.addEventListener('click', handleClicks, false);
    document.addEventListener('mouseover', handleMouseover, false);
</script>
</body>
</html>
```

### Uso de `target` e `relatedTarget`

A propriedade `relatedTarget` do evento de `mouseover` mantém o nó de onde o mouse estava sobre anteriormente. Para o evento de `mouseout`, mantém o nó para onde o mouse se moveu.

| Tipo de Evento | event.target | event.relatedTarget |
| --- | --- | --- |
| `mouseover` | O EventTarget do qual o dispositivo apontador entrou. | O EventTarget do qual o dispositivo apontador saiu. |
| `mouseout` | O EventTarget do qual o dispositivo apontador saiu. | O EventTarget do qual o dispositivo apontador entrou. |

TODO: Necessário descrição complemento sobre eventos de `dragenter` e `dragexit`.

#### Exemplo
```

<hbox id="outer">
  <hbox id="inner"
        onmouseover="dump('mouseover ' + event.relatedTarget.id + ' > ' + event.target.id + '\n');"
        onmouseout="dump('mouseout  ' + event.target.id + ' > ' + event.relatedTarget.id + '\n');"
        style="margin: 100px; border: 10px solid black; width: 100px; height: 100px;" />
</hbox>
```


Event.preventDefault() - APIs da Web

Event.preventDefault()
======================

Resumo
------

Cancela o evento se for cancelável, sem parar a propagação do mesmo.

Sintaxe
-------
```

event.preventDefault();
```

Exemplo
-------

Alternar é a ação padrão de clicar em uma caixa de seleção. Este exemplo demonstra como impedir que isso aconteça:

```html
<!doctype html>
<html>
  <head>
    <title>preventDefault example</title>

    <script>
 function stopDefAction(evt) {
 evt.preventDefault();
 }

 document
 .getElementById("my-checkbox")
 .addEventListener("click", stopDefAction, false);
 </script>
  </head>

  <body>
    <p>Please click on the checkbox control.</p>

    <form>
      <input type="checkbox" id="my-checkbox" />
      <label for="my-checkbox">Checkbox</label>
    </form>
  </body>
</html>
```

Você pode ver o `preventDefault` em ação aqui.

O exemplo a seguir demonstra como um input com texto inválido pode ser parado ao chegar ao campo de entrada com o preventDefault().

```html
<!DOCTYPE html>
<html>
<head>
<title>preventDefault example</title>

<script>
```

```js
function Init() {
  var myTextbox = document.getElementById("my-textbox");
  myTextbox.addEventListener("keypress", checkName, false);
}

function checkName(evt) {
  var charCode = evt.charCode;
  if (charCode != 0) {
    if (charCode < 97 || charCode > 122) {
      evt.preventDefault();
      alert(
        "Please use lowercase letters only." +
          "\n" +
          "charCode: " +
          charCode +
          "\n",
      );
    }
  }
}
```

```html
</script>
</head>
<body onload="Init ()">
    <p>Please enter your name using lowercase letters only.</p>
    <form>
        <input type="text" id="my-textbox" />
    </form>
</body>
</html>
```

Aqui está o resultado do código anterior:

Notas
-----

Chamar preventDefault durante qualquer fase do fluxo de eventos cancela o evento, o que significa que qualquer ação padrão normalmente feita pela aplicação como um resultado do evento não ocorrerá.

**Nota:** A partir do Gecko 6.0, chamar o `preventDefault()` faz com que o `event.defaultPrevented` se torne true.

Você pode usar o event.cancelable (en-US) para checar se o evento é cancelável. Chamar o `preventDefault` para um evento não cancelável não fará efeito.

`Se o preventDefault não parar a propagação do evento através do DOM. event.stopPropagation deve ser usada para isso.`

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-preventdefault③ |

Compatibilidade com navegadores
-------------------------------

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


Event.srcElement - APIs da Web

Event.srcElement
================

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

**`Event.srcElement`** é uma propriedade *alias* para a propriedade padrão `Event.target`. É específica para versões antigas do Microsoft Internet Explorer.

Especificações
--------------

Não é parte de nenhuma especificação.

Microsoft tem uma descrição na MSDN.

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `Window.event`


Event.currentTarget - APIs da Web

Event.currentTarget
===================

Identifica o alvo atual para o evento quando o event percorre o DOM. O currentTarget sempre se refere ao elemento associado ao event handler, ao invés do event.target que identifica o elemento ao qual o evento ocorreu.

Exemplo
-------

`event.currentTarget` é bom para ser usado quando nós queremos associar o mesmo event handler para vários elementos.

```js
function hide(e) {
  e.currentTarget.style.visibility = "hidden";
  console.log(e.currentTarget);
  // Quando essa função é usada como um event
  // handler: this === e.currentTarget
}

var ps = document.getElementsByTagName("p");

for (var i = 0; i < ps.length; i++) {
  // console: print the clicked <p> element
  ps[i].addEventListener("click", hide, false);
}
// console: print <body>
document.body.addEventListener("click", hide, false);

// Clique e faça os parágrafos desaparecerem
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-currenttarget② |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

Comparativo dos Event Targets


Event.defaultPrevented - APIs da Web

Event.defaultPrevented
======================

### Resumo

Retorna um booleano que indica se ou não `event.preventDefault()` foi chamado no evento.

**Nota:** Você deve usar isso em vez de a não-padrão, método desatualizado `getPreventDefault()` (ver Firefox bug 691151).

### Sintaxe
```

bool = event.defaultPrevented
```

### Exemplo
```

 if (e.defaultPrevented) {
   /* o padrão foi impedido */
 }
```

### Compatibilidade do navegador

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


Event.stopImmediatePropagation() - APIs da Web

Event.stopImmediatePropagation()
================================

Evita que outros *listeners* escutem o evento.

Sintaxe
-------
```

event.stopImmediatePropagation();
```

Notas
-----

No caso de um evento onde vários *listeners* o estão escutando, os mesmos são disparados na ordem em que foram adicionados. Porém, se durante uma chamada (ou disparo), `event.stopImmediatePropagation()` for chamado, os demais *listeners* não serão disparados.

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-stopimmediatepropagation① |

Compatibilidade com navegadores
-------------------------------

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


Event.initEvent() - APIs da Web

Event.initEvent()
=================

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

O método **`Event.initEvent()`** é usado para inicializar o valor de um `event` criado usando `Document.createEvent()` (en-US).

Eventos inicializados desta maneira precisam ter sido criados com o método `Document.createEvent()` (en-US). Este método precisar ser chamado para definir o evento antes de ser despachado, usando `EventTarget.dispatchEvent()`. Uma vez despachado, não faz mais nada.

**Nota:** **Não use esse método mais, pois está depreciado.**

Ao invés, use construtores de eventos específicos, como `Event()`. A página sobre Criando e disparando eventos (en-US) detalha mais informações sobre o uso desses eventos.

Syntax
------
```

event.initEvent(tipo, bubbles, cancelable);
```

`tipo`

É um `DOMString` definido o tipo do evento.

`bolhas`

É um `Boolean` decidindo se o evento precisa ser enviado para cima, na cadeia de eventos ou não. Uma vez definido, a propriedade read-only `Event.bubbles` (en-US) irá informar o seu valor.

`cancelable`

É um `Boolean` definindo se o evento pode ser cancelado. Uma vez definido, a propriedade read-only `Event.cancelable` (en-US) will irá informar o seu valor.

Exemplo
-------
```

// Cria o evento.
var event = document.createEvent('Event');

// Cria um evento de clique que borbulha e
// não pode ser cancelado
event.initEvent('click', true, false);

// Escuta este evento.
elem.addEventListener('click', function (e) {
  // e.target matches elem
}, false);

elem.dispatchEvent(event);
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-initevent① |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* O construtor para usar ao invés deste método descontinuado: `Event()`. Construtores mais específicos também podem ser usados.


AbortSignal.aborted - APIs da Web

AbortSignal.aborted
===================

**Experimental:** **Esta é uma tecnologia experimental (en-US)**
Verifique a tabela de compatibilidade entre Navegadores cuidadosamente antes de usar essa funcionalidade em produção.

A propriedade **`aborted`** é apenas para leitura e fornece um valor `Boolean` (en-US) indicando se as solicitações ao objeto sinal de comunicação DOM forão abortadas (`true`) ou não (`false`).

Sintaxe
-------

```js
var isAborted = abortSignal.aborted;
```

### Valor

Um valor `Boolean` (en-US)

Exemplos
--------

No fragmento abaixo, criamos um novo objeto `AbortController` e recebemos dele um sinal `AbortSignal` (disponível na propriedade `signal`). Depois checamos se o sinal foi ou não abortado usando a propriedade `aborted`, e então enviamos um log apropriado para o console.

```js
var controller = new AbortController();
var signal = controller.signal;

// ...

signal.aborted
  ? console.log("Pedido foi abortado")
  : console.log("Pedido nao foi abortado");
```

Especificações
--------------

| Specification |
| --- |
| DOM Standard # ref-for-dom-abortsignal-aborted① |

Compatibilidade com navegadores
-------------------------------

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

Veja Também
-----------

* Documentação de busca API


HTMLElement.offsetHeight - APIs da Web

HTMLElement.offsetHeight
========================

A propriedade **`HTMLElement.offsetHeight`** é somente leitura e retorna um valor do tipo inteiro a altura de um elemento incluindo padding-top+padding-bottom+border-top+border-bottom.

Typically, an element's `offsetHeight` is a measurement in pixels of the element's CSS height, including border, padding and the element's horizontal scrollbar (if present, if rendered).

For the document body object, the measurement includes total linear content height instead of the element's CSS height. Floated elements extending below other linear content are ignored.

**Nota:** This property will round the value to an integer. If you need a fractional value, use `element.getBoundingClientRect()`.

Syntax
------
```

var intElemOffsetHeight = element.offsetHeight;
```

*intElemOffsetHeight* is a variable storing an integer corresponding to the offsetHeight pixel value of the element. The offsetHeight property is read-only.

Example
-------

![Image:Dimensions-offset.png](/pt-BR/docs/Web/API/HTMLElement/offsetHeight/dimensions-offset.png)

The example image above shows a scrollbar and an offsetHeight which fits on the window. However, non-scrollable elements may have large offsetHeight values, much larger than the visible content. These elements are typically contained within scrollable elements; consequently these non-scrollable elements may be completely or partly invisible, depending on the scrollTop setting of the scrollable container.

Especificações
--------------

| Specification |
| --- |
| CSSOM View Module # dom-htmlelement-offsetheight |

Compatibilidade com navegadores
-------------------------------

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

See Also
--------

* `Element.clientHeight`
* `Element.scrollHeight` (en-US)
* `HTMLElement.offsetWidth`
* Determining the dimensions of elements (en-US)
* MSDN: Measuring Element Dimension and Location


Element.accessKey - APIs da Web

Element.accessKey
=================

A propriedade **Element.accessKey** define a tecla pelo qual o usuário pode pressionar para saltar para este elemento.

**Nota:** Nota: *A propriedade **Element.accessKey** é raramente usada por causa dos conflitos múltiplos com os atalhos pré-definidos nos navegadores. Para contornar isto, os navegadores implementam o comportamento da tecla de acesso se as teclas são pressionadas com outras teclas "qualificadas" (como Alt + tecla de acesso).*


HTMLElement.offsetParent - APIs da Web

HTMLElement.offsetParent
========================

A propriedade somente de leitura **`HTMLElement.offsetParent`** retorna uma referência ao objeto ao qual está contido(mais próximo na hierarquia do conteúdo) posicionado contendo o elemento. Caso o elemento não esteja posicionado, mais próximo a célula da tabela ou do elemento raiz (nos padrões do modo de conformidade do `html; no modo quirks de redenrização) é o` `offsetParent`. quando o elemento está definido `style.display` para "none", `offsetParent` retorna null. A propriedade `offsetParent` é útil devido a `offsetTop` e `offsetLeft` serem relativos ao seu preenchimento da borda.
```

parentObj = element.offsetParent;
```

* *parentObj* é uma referência de objeto ao elemento no qual o elemento corrente é offset.
Especificações
--------------

| Specification |
| --- |
| CSSOM View Module # dom-htmlelement-offsetparent |

Compatibilidade com navegadores
-------------------------------

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


GlobalEventHandlers.onchange - APIs da Web

GlobalEventHandlers.onchange
============================

A propriedade `onchange` determina e retorna o manipulador de eventos para o evento `change (en-US)`.

Syntax
------
```

element.onchange = handlerFunction;
var handlerFunction = element.onchange;
```

`handlerFunction` deve ser ou `null` ou uma função JavaScript especificando o manipulador para o evento.

Notas
-----

Veja a página do manipulador de eventos do DOM (en-US) para informações sobre como trabalhar com manipuladores `on...`

Veja a documentação do evento `change (en-US)` para informações sobre o evento.

Especificações
--------------

| Specification |
| --- |
| HTML Standard # event-change |
| HTML Standard # handler-onchange |

Compatibilidade com navegadores
-------------------------------

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


HTMLElement.offsetLeft - APIs da Web

HTMLElement.offsetLeft
======================

O **`HTMLElement.offsetLeft`** é um método apenas de leitura que retorna a medida, em pixels, da distância do canto superior esquerdo do elemento atual para o nó `HTMLElement.offsetParent`.

Para elementos "block-level", que ocupam todo o espaço do elemento pai, o `offsetTop`, `offsetLeft`, `offsetWidth`, e `offsetHeight` representam a borda de um elemento relativo ao `offsetParent`.

Entretando, para elementos "inline-level" (como o **span**) que podem envolver de uma linha para outra, o `offsetTop` e `offsetLeft` representam a posição da primeira borda (use `Element.getClientRects()` (en-US) para retornar a largura e altura), enquanto `offsetWidth` e `offsetHeight` representam as dimensões do bloco delimitador (use `Element.getBoundingClientRect()` pra retornar sua posição). Portanto, um bloco que possua um left, top, widht ou height do `offsetLeft, offsetTop, offsetWidth` e `offsetHeight` não será um delimitador para um span com texto envolvido.

Sintaxe
-------
```

left = element.offsetLeft;
```

`left` é um número inteiro representando o deslocamento para esquerda, em pixels, do elemento pai mais próximo posicionado com relative.

Exemplo
-------
```

var colorTable = document.getElementById("t1");
var tOLeft = colorTable.offsetLeft;

if (tOLeft > 5) {
  // deslocamento à esquerda maior que 5: faça alguma coisa
}
```

Esse exemplo mostra uma frase 'longa' envolvida por uma div com uma borda azul, e uma caixa vermelha que deveria delimitar o span.

![Image:offsetLeft.jpg](/pt-BR/docs/Web/API/HTMLElement/offsetLeft/offsetleft.jpg)
```

<div style="width: 300px; border-color:blue;
  border-style:solid; border-width:1;">
  <span>Short span. </span>
  <span id="long">Long span that wraps within this div.</span>
</div>

<div id="box" style="position: absolute; border-color: red;
  border-width: 1; border-style: solid; z-index: 10">
</div>

<script>
  var box = document.getElementById("box");
  var long = document.getElementById("long");
  box.style.left = long.offsetLeft + document.body.scrollLeft + "px";
  box.style.top = long.offsetTop + document.body.scrollTop + "px";
  box.style.width = long.offsetWidth + "px";
  box.style.height = long.offsetHeight + "px";
</script>
```

Especificações
--------------

| Specification |
| --- |
| CSSOM View Module # dom-htmlelement-offsetleft |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `HTMLElement.offsetParent`, `HTMLElement.offsetTop`, `HTMLElement.offsetWidth`, `HTMLElement.offsetHeight`


HTMLElement.contentEditable - APIs da Web

HTMLElement.contentEditable
===========================

A propriedade **`HTMLElement.contentEditable`** é usada para indicar se o elemento é editável ou não. Esse atributo enumerado pode ter os seguintes valores:

* `"true"` Indica que o elemento é editável;
* `"false"` Indica que o elemento não pode ser editável;
* `"inherit"` Indica que o elemento herda o status editável de seu pai.

Você pode usar a propriedade `HTMLElement.isContentEditable` (en-US) para testar o valor calculado `Boolean` (en-US) desta propriedade.

Sintaxe
-------
```

editable = element.contentEditable element.contentEditable= "true"
```

Especificações
--------------

| Specification |
| --- |
| HTML Standard # contenteditable |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `HTMLElement.isContentEditable` (en-US)
* The contenteditable global attribute.
* Why ContentEditable is Terrible, Or: How the Medium Editor Works


Node.innerText - APIs da Web

Node.innerText
==============

Resumo
------

**`Node.innerText`** é uma propriedade que representa o conteúdo textual "renderizado" de um nó e seus descendentes. Usada como getter, retorna de maneira aproximada o texto que o usuário obteria caso tivesse selecionado o conteúdo e copiado para a área de transferência. Este recurso fora introduzido originalmente pelo Internet Explorer, mas foi oficialmente especificado no padrão HTML apenas em 2016, sendo adotado por todos os principais navegadores a partir de então.

`Node.textContent` é uma alternativa similar, embora existam diferenças significativas entre as duas.

Especificações
--------------

| Specification |
| --- |
| HTML Standard # the-innertext-idl-attribute |

Compatibilidade com navegadores
-------------------------------

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

Ver também
----------

* `HTMLElement.outerText` (en-US)
* `Element.innerHTML`


HTMLElement.click() - APIs da Web

HTMLElement.click()
===================

O método **`HTMLElement.click()`** simula o clique do mouse em um elemento.

Quando clique é usado com elementos que o suportam (por exemplo, um dos `<input>` tipos listados acima), ele também dispara evento de clique do elemento que vai propagar pelos elementos mais acima na árvore de documentos (ou cadeia do evento) e disparando seus eventos de clique também. No entanto, o evento de clique, propagado como bubble, não vai iniciar a navegação do elemento `<a>` como se uma verdadeiro clique do mouse tivesse sido recebido.

Sintaxe
-------
```

elt.click()
```

Especificações
--------------

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

Compatibilidade com navegadores
-------------------------------

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


HTMLElement.offsetTop - APIs da Web

HTMLElement.offsetTop
=====================

O **`HTMLElement.offsetTop`** é um método apenas de leitura que retorna a medida, em pixels, da distância do elemento atual em relação ao topo do `offsetParent`.

Sintaxe
-------
```

topPos = element.offsetTop;
```

### Parâmetros

* `topPos` é o número, em pixels, que representa a distância do elemento para o topo do elemento pai mais próximo posicionado com relative.
Exemplo
-------

```js
var d = document.getElementById("div1");
var topPos = d.offsetTop;

if (topPos > 10) {
  // deslocamento em relação ao topo maior
  // que 10pixels do topo
}
```

Especificações
--------------

| Specification |
| --- |
| CSSOM View Module # dom-htmlelement-offsettop |

Compatibilidade com navegadores
-------------------------------

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


HTMLElement.offsetWidth - APIs da Web

HTMLElement.offsetWidth
=======================

`A propriedade HTMLElement.offsetWidth` é de somente leitura e retorna a largura de um elemento no layout. Normalmente, o `offsetWidth` é uma medida que inclui as bordas do elemento, seu padding horizontal e o vertical scrollbar (se presente e renderizado) e também a largura CSS do elemento.

Sintaxe
```

var offsetWidth =element.offsetWidth;
```

`offsetWidth` é uma propriedade somente leitura.

**Nota:** Esta propriedade irá arredondar o valor para um inteiro. se você precisa um valor fracionado, use `element.getBoundingClientRect()`.

Exemplo
-------

![Image:Dimensions-offset.png](/pt-BR/docs/Web/API/HTMLElement/offsetWidth/dimensions-offset.png)

Especificações
--------------

| Specification |
| --- |
| CSSOM View Module # dom-htmlelement-offsetwidth |

Compatibilidade com navegadores
-------------------------------

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

Veja também
-----------

* `Element.clientWidth` (en-US)
* `Element.scrollWidth`
* Determinando as dimensões dos elementos (en-US)


MessagePort.postMessage() - APIs da Web

MessagePort.postMessage()
=========================

O método **`postMessage()`** da interface `MessagePort` (en-US) envia uma mensagem da porta e opcionalmente transfere a propriedade do objeto para outros contexto de navegação.

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

Syntax
------
```

port.postMessage(message, transferList);
```

### Returns

Vazio.

### Parameters

message

A mensagem que você quer enviar atravéz do canal. Esta mensagem pode ser de qualquer tipo de dados basico. Multiplos items podem ser enviados com diferentestes tipos de dados como em um Array.

transferList Optional

`Transferable` objects to be transferred — these objects have their ownership transferred to the receiving browsing context, so are no longer usable by the sending browsing context.

Example
-------

In the following code block, you can see a new channel being created using the `MessageChannel.MessageChannel` constructor. When the IFrame has loaded, we pass `MessageChannel.port2` (en-US) to the IFrame using `window.postMessage` (en-US) along with a message. The `handleMessage` handler then responds to a message being sent back from the IFrame using `onmessage`, putting it into a paragraph — `MessageChannel.port1` (en-US) is listened to, to check when the message arrives.

```js
var channel = new MessageChannel();
var para = document.querySelector("p");

var ifr = document.querySelector("iframe");
var otherWindow = ifr.contentWindow;

ifr.addEventListener("load", iframeLoaded, false);

function iframeLoaded() {
  otherWindow.postMessage("Hello from the main page!", "\*", [channel.port2]);
}

channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}
```

For a full working example, see our channel messaging basic demo on Github (run it live too).

Especificações
--------------

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

Compatibilidade com navegadores
-------------------------------

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

See also
--------

* Using channel messaging (en-US)