Aplicando estilos e cores - APIs da Web

Aplicando estilos e cores
=========================

* « Previous
* Next »

No capítulo sobre desenhando formas com canvas, usamos apenas os estilos padrões de preenchimento e linha. Aqui vamos explorar as opções do canvas que temos à nossa disposição para tornar nossos desenhos um pouco mais atraentes. Você aprenderá a adicionar cores diferentes, estilos de linhas, gradientes, padrões e sombras aos seus desenhos.

Cores
-----

Até agora só vimos métodos do contexto de desenho. Se quisermos aplicar cores a uma forma, existem duas propriedades importantes que podemos utilizar: `fillStyle` e `strokeStyle`.

`fillStyle = color`

Define o estilo usado ao preencher (fill) formas.

`strokeStyle = color` (en-US)

Define o estilo para os contornos (strokes) das formas.

`color` é uma string que representa um CSS `<color>`, um objeto gradiente, ou um objeto padrão. Examinaremos sobre objetos de gradiente e padrão mais tarde. Por padrão, a cor do contorno (stroke color) e a cor de preenchimento (fill color) estão definidos como preto (valor de cor no CSS é `#000000`).

**Nota:** Quando você definir as propriedades `strokeStyle` e/ou `fillStyle` , o novo valor será o padrão para todas as formas desenhadas a partir de então. Para toda forma que você quiser uma cor diferente, você vai precisar alterar o valor da propriedade `fillStyle` ou `strokeStyle`.

As strings validas que você pode inserir devem, de acordo com a especificação ser valores CSS `<color>`. Cada um dos exemplos a seguir, descrevem a mesma cor.

```js
// these all set the fillStyle to 'orange'

ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255, 165, 0)";
ctx.fillStyle = "rgba(255, 165, 0, 1)";
```

### Um `fillStyle` exemplo

Neste exemplo, nós vamos mais uma vez utilizar dois `for` loops para desenhar uma grade de retângulos, cada um com uma cor diferente. A imagem do resultado, deve parecer como a captura de tela. Não existe nada de muito espetacular acontecendo aqui. Nós usamos as duas variéveis `i` and `j` para gerar uma única cor em RGB para cada quadrado, e apenas modificando os valores vermelho e verde. O canal azul possui um valor fixo. Modificando os canais, você pode gerar todos os tipos de paletas. Aumentando os passos, você pode alcançar algo que se parece com a paleta de cores dos usuários de Photoshop.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 6; i++) {
    for (var j = 0; j < 6; j++) {
      ctx.fillStyle =
        "rgb(" +
        Math.floor(255 - 42.5 \* i) +
        "," +
        Math.floor(255 - 42.5 \* j) +
        ",0)";
      ctx.fillRect(j \* 25, i \* 25, 25, 25);
    }
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

O resultado se parece com isto:

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Um `strokeStyle` exemplo

Este exemplo é similar com o anterior, porém utiliza a propriedade `strokeStyle` para alterar a cor de contorno das formas. Nós usamos o método `arc()` para desenhar círculos ao invés de quadrados.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 6; i++) {
    for (var j = 0; j < 6; j++) {
      ctx.strokeStyle =
        "rgb(0," +
        Math.floor(255 - 42.5 \* i) +
        "," +
        Math.floor(255 - 42.5 \* j) +
        ")";
      ctx.beginPath();
      ctx.arc(12.5 + j \* 25, 12.5 + i \* 25, 10, 0, Math.PI \* 2, true);
      ctx.stroke();
    }
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

O resultado se parece com isto:

| Screenshot | Live sample |
| --- | --- |
|  |  |

Transparência
-------------

Além de desenhar formas opacas na tela, também podemos desenhar formas semi-transparentes (ou translúcidas). Isso é feito definindo a propriedade globalAlpha ou atribuindo uma cor semitransparente ao estilo de stroke e / ou fill style.

`globalAlpha = transparencyValue` (en-US)

Aplica o valor de transparência especificado a todas as formas futuras desenhadas na tela. O valor deve estar entre 0,0 (totalmente transparente) e 1,0 (totalmente opaco). Este valor é 1.0 (totalmente opaco) por padrão.

A propriedade globalAlpha pode ser útil se você quiser desenhar muitas formas na tela com transparência semelhante, mas, caso contrário, geralmente é mais útil definir a transparência em formas individuais ao definir suas cores.

Como as propriedades strokeStyle e fillStyle aceitam os valores de cor CSS rgba, podemos usar a notação a seguir para atribuir uma cor transparente a eles.

```js
// Assigning transparent colors to stroke and fill style

ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
```

A função rgba () é semelhante à função rgb (), mas possui um parâmetro extra. O último parâmetro define o valor da transparência dessa cor específica. O intervalo válido é novamente entre 0,0 (totalmente transparente) e 1,0 (totalmente opaco).

### Um exemplo globalAlpha

Neste exemplo, desenharemos um plano de fundo de quatro quadrados coloridos diferentes. Além disso, desenharemos um conjunto de círculos semi-transparentes. A propriedade globalAlpha é configurada em 0.2, que será usada para todas as formas a partir desse ponto. Cada passo no loop for desenha um conjunto de círculos com um raio crescente. O resultado final é um gradiente radial. Ao sobrepor cada vez mais círculos um sobre o outro, reduzimos efetivamente a transparência dos círculos que já foram desenhados. Ao aumentar a contagem de etapas e, com efeito, desenhar mais círculos, o plano de fundo desapareceria completamente do centro da imagem.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  // draw background
  ctx.fillStyle = "#FD0";
  ctx.fillRect(0, 0, 75, 75);
  ctx.fillStyle = "#6C0";
  ctx.fillRect(75, 0, 75, 75);
  ctx.fillStyle = "#09F";
  ctx.fillRect(0, 75, 75, 75);
  ctx.fillStyle = "#F30";
  ctx.fillRect(75, 75, 75, 75);
  ctx.fillStyle = "#FFF";

  // set transparency value
  ctx.globalAlpha = 0.2;

  // Draw semi transparent circles
  for (i = 0; i < 7; i++) {
    ctx.beginPath();
    ctx.arc(75, 75, 10 + 10 \* i, 0, Math.PI \* 2, true);
    ctx.fill();
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Um exemplo usando o `rgba()`

Neste segundo exemplo, fazemos algo semelhante ao anterior, mas em vez de desenhar círculos uns sobre os outros, desenhei pequenos retângulos com crescente opacidade. O uso de rgba () oferece um pouco mais de controle e flexibilidade, pois podemos definir o estilo de preenchimento e traçado/stroke individualmente.

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

  // Draw background
  ctx.fillStyle = "rgb(255, 221, 0)";
  ctx.fillRect(0, 0, 150, 37.5);
  ctx.fillStyle = "rgb(102, 204, 0)";
  ctx.fillRect(0, 37.5, 150, 37.5);
  ctx.fillStyle = "rgb(0, 153, 255)";
  ctx.fillRect(0, 75, 150, 37.5);
  ctx.fillStyle = "rgb(255, 51, 0)";
  ctx.fillRect(0, 112.5, 150, 37.5);

  // Draw semi transparent rectangles
  for (var i = 0; i < 10; i++) {
    ctx.fillStyle = "rgba(255, 255, 255, " + (i + 1) / 10 + ")";
    for (var j = 0; j < 4; j++) {
      ctx.fillRect(5 + i \* 14, 5 + j \* 37.5, 14, 27.5);
    }
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

Line styles
-----------

Existem várias propriedades que permitem estilizar linhas.

`lineWidth = value` (en-US)

Define a largura das linhas desenhadas no futuro.

`lineCap = type` (en-US)

Define a aparência dos fins das linhas.

`lineJoin = type` (en-US)

Define a aparência dos "cantos" onde as linhas se encontram.

`miterLimit = value` (en-US)

Estabelece um limite na mitra quando duas linhas se juntam em um ângulo agudo, para permitir controlar a espessura da junção.

`getLineDash()` (en-US)

Retorna a matriz de padrão de traço de linha atual que contém um número par de números não negativos

`setLineDash(segments)` (en-US)

Define o padrão de traço da linha atual.

`lineDashOffset = value` (en-US)

Especifica onde iniciar uma matriz de traços em uma linha.

Você entenderá melhor o que eles fazem observando os exemplos abaixo.

### Um exemplo lineWidth

A largura da linha é a espessura do traçado centralizado no caminho especificado. Em outras palavras, a área desenhada se estende até a metade da largura da linha em ambos os lados do caminho.

Como as coordenadas da tela não fazem referência direta aos pixels, deve-se tomar cuidado especial para obter linhas horizontais e verticais nítidas.

No exemplo abaixo, 10 linhas retas são desenhadas com larguras de linhas crescentes. A linha na extrema esquerda tem 1,0 unidades de largura. No entanto, as linhas de espessura à esquerda e todas as outras linhas com número inteiro ímpar não aparecem nítidas, devido ao posicionamento do caminho.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  for (var i = 0; i < 10; i++) {
    ctx.lineWidth = 1 + i;
    ctx.beginPath();
    ctx.moveTo(5 + i \* 14, 5);
    ctx.lineTo(5 + i \* 14, 140);
    ctx.stroke();
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

 A obtenção de linhas nítidas requer a compreensão de como os caminhos são traçados. Nas imagens abaixo, a grade representa a grade de coordenadas da tela. Os quadrados entre as linhas de grade são pixels reais na tela. Na primeira imagem da grade abaixo, um retângulo de (2,1) a (5,5) é preenchido. A área inteira entre eles (vermelho claro) cai nos limites dos pixels, portanto, o retângulo preenchido resultante terá bordas nítidas.

 ![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors/canvas-grid.png)

Se você considerar um caminho de (3,1) a (3,5) com uma espessura de linha de 1,0, você terminará com a situação na segunda imagem. A área real a ser preenchida (azul escuro) se estende apenas até a metade dos pixels dos dois lados do caminho. Uma aproximação disso deve ser renderizada, o que significa que esses pixels são sombreados apenas parcialmente e resultam em toda a área (azul claro e azul escuro) sendo preenchida com uma cor apenas metade da escuridão da cor real do traço. É o que acontece com a linha de largura 1.0 no código de exemplo anterior.

Para corrigir isso, você precisa ser muito preciso na criação do seu caminho. Sabendo que uma linha de largura 1,0 estenderá meia unidade para ambos os lados do caminho, criar o caminho de (3,5,1) a (3,5,5) resulta na situação da terceira imagem - a largura da linha 1,0 termina completamente e preenchendo com precisão uma única linha vertical de pixel.

**Nota:** **Nota: Esteja ciente de que, no nosso exemplo de linha vertical, a posição Y ainda faz referência a uma posição de linha de grade inteira - se não tivesse, veríamos pixels com meia cobertura nos pontos de extremidade (mas observe também que esse comportamento depende do estilo lineCap atual cujo valor padrão é butt; você pode calcular traçados consistentes com coordenadas de meio pixel para linhas de largura ímpar, configurando o estilo lineCap como quadrado, para que a borda externa do traçado ao redor do ponto de extremidade seja estendida automaticamente para cobrir o pixel inteiro exatamente).**

Observe também que apenas os pontos de extremidade inicial e final de um caminho são afetados: se um caminho for fechado com closePath (), não haverá ponto inicial e final; em vez disso, todos os pontos de extremidade no caminho são conectados ao segmento anterior e ao próximo anexado usando a configuração atual do estilo lineJoin, cujo valor padrão é mitra, com o efeito de estender automaticamente as bordas externas dos segmentos conectados ao seu ponto de interseção. que o traçado renderizado cobrirá exatamente os pixels completos centralizados em cada ponto final se esses segmentos conectados forem horizontais e / ou verticais). Veja as próximas duas seções para demonstrações desses estilos de linha adicionais.

Para linhas de largura uniforme, cada metade acaba sendo uma quantidade inteira de pixels, portanto, você deseja um caminho entre pixels (ou seja, (3,1) a (3,5)), em vez de no meio dos pixels .

Embora seja um pouco doloroso ao trabalhar inicialmente com gráficos 2D escalonáveis, prestar atenção à grade de pixels e à posição dos caminhos garante que seus desenhos pareçam corretos, independentemente da escala ou de qualquer outra transformação envolvida. Uma linha vertical de 1,0 largura desenhada na posição correta se tornará uma linha nítida de 2 pixels quando aumentada em 2 e aparecerá na posição correta.

### Exemplo lineCap

A propriedade lineCap determina como os pontos finais de cada linha são desenhados. Existem três valores possíveis para essa propriedade e são: bunda, redondo e quadrado. Por padrão, essa propriedade está configurada para butt.
 ![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors/canvas_linecap.png)

`butt`

As extremidades das linhas são quadradas nos pontos finais.

`round`

 As extremidades das linhas são arredondadas.
 arredondadas.

`square`

As extremidades das linhas são ajustadas ao quadrado, adicionando uma caixa com a mesma largura e metade da altura da espessura da linha.

Neste exemplo, desenharemos três linhas, cada uma com um valor diferente para a propriedade lineCap. Também adicionei dois guias para ver as diferenças exatas entre os três. Cada uma dessas linhas começa e termina exatamente nesses guias.

A linha à esquerda usa a opção de topo padrão. Você notará que está desenhado completamente alinhado com as guias. O segundo está definido para usar a opção redonda. Isso adiciona um semicírculo ao final que tem um raio com metade da largura da linha. A linha à direita usa a opção quadrada. Isso adiciona uma caixa com largura igual e metade da altura da espessura da linha.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var lineCap = ["butt", "round", "square"];

  // Draw guides
  ctx.strokeStyle = "#09f";
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(140, 10);
  ctx.moveTo(10, 140);
  ctx.lineTo(140, 140);
  ctx.stroke();

  // Draw lines
  ctx.strokeStyle = "black";
  for (var i = 0; i < lineCap.length; i++) {
    ctx.lineWidth = 15;
    ctx.lineCap = lineCap[i];
    ctx.beginPath();
    ctx.moveTo(25 + i \* 50, 10);
    ctx.lineTo(25 + i \* 50, 140);
    ctx.stroke();
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Um exemplo de lineJoin

A propriedade lineJoin determina como dois segmentos de conexão (de linhas, arcos ou curvas) com comprimentos diferentes de zero em uma forma são unidos (segmentos degenerados com comprimentos zero, cujos pontos finais e pontos de controle especificados são exatamente na mesma posição, são ignorados) .

Existem três valores possíveis para essa propriedade: round, chanfro e mitra. Por padrão, essa propriedade está configurada para mitra. Observe que a configuração lineJoin não terá efeito se os dois segmentos conectados tiverem a mesma direção, porque nenhuma área de junção será adicionada neste caso.
 ![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors/canvas_linejoin.png)

`round`

Arredonda os cantos de uma forma preenchendo um setor adicional de disco centralizado no ponto final comum dos segmentos conectados. O raio desses cantos arredondados é igual à metade da largura da linha.

`bevel`

Preenche uma área triangular adicional entre o ponto final comum dos segmentos conectados e os cantos retangulares externos separados de cada segmento.

`miter`

Os segmentos conectados são unidos estendendo suas bordas externas para se conectarem em um único ponto, com o efeito de preencher uma área adicional em forma de losango. Essa configuração é efetuada pela propriedade miterLimit, explicada abaixo.

O exemplo abaixo desenha três caminhos diferentes, demonstrando cada uma dessas três configurações de propriedade lineJoin; a saída é mostrada acima.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var lineJoin = ["round", "bevel", "miter"];
  ctx.lineWidth = 10;
  for (var i = 0; i < lineJoin.length; i++) {
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(-5, 5 + i \* 40);
    ctx.lineTo(35, 45 + i \* 40);
    ctx.lineTo(75, 5 + i \* 40);
    ctx.lineTo(115, 45 + i \* 40);
    ctx.lineTo(155, 5 + i \* 40);
    ctx.stroke();
  }
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Uma demonstração da propriedade miterLimit

Como você viu no exemplo anterior, ao unir duas linhas com a opção de esquadria, as bordas externas das duas linhas de junção são estendidas até o ponto em que elas se encontram. Para linhas com ângulos amplos entre si, esse ponto não está longe do ponto de conexão interno. No entanto, à medida que os ângulos entre cada linha diminuem, a distância (comprimento da mitra) entre esses pontos aumenta exponencialmente.

A propriedade miterLimit determina a que distância o ponto de conexão externo pode ser colocado do ponto de conexão interno. Se duas linhas excederem esse valor, uma junção de chanfro será desenhada. Observe que o comprimento máximo da esquadria é o produto da largura da linha medida no sistema de coordenadas atual, pelo valor dessa propriedade miterLimit (cujo valor padrão é 10.0 no HTML `<canvas>`), portanto, o O miterLimit pode ser definido independentemente da escala de exibição atual ou de quaisquer transformações afins de caminhos: apenas influencia a forma efetivamente renderizada das arestas da linha.

Mais exatamente, o limite da mitra é a proporção máxima permitida do comprimento da extensão (na tela HTML, é medida entre o canto externo das arestas unidas da linha e o ponto de extremidade comum dos segmentos de conexão especificados no caminho) pela metade do espessura da linha. Pode ser definido de maneira equivalente como a proporção máxima permitida da distância entre os pontos interno e externo da junção das arestas e a largura total da linha. Em seguida, é igual ao coecante da metade do ângulo interno mínimo dos segmentos de conexão abaixo dos quais nenhuma junção de esquadria será renderizada, mas apenas uma junção de chanfro:

* `miterLimit` = **max** `miterLength` / `lineWidth` = 1 / **sin** ( **min** *θ* / 2 )
* O limite padrão de esquadria de 10.0 removerá todos os mitros para ângulos agudos abaixo de 11 graus.
* Um limite de esquadria igual a √2 ≈ 1.4142136 (arredondado para cima) retira os mitros para todos os ângulos agudos, mantendo as juntas de esquadria apenas para ângulos obtusos ou retos.
* Um limite de mitra igual a 1,0 é válido, mas desativará todos os atenuadores.
* Valores abaixo de 1,0 são inválidos para o limite de mitra.

Aqui está uma pequena demonstração na qual você pode definir o mitreLimit dinamicamente e ver como isso afeta as formas na tela. As linhas azuis mostram onde estão os pontos inicial e final de cada uma das linhas no padrão em zigue-zague.

Se você especificar um valor de miterLimite abaixo de 4.2 nesta demonstração, nenhum dos cantos visíveis poderá ser uma extensão de mitra, mas apenas com um pequeno canal próximo às linhas azuis; com um limite máximo acima de 10, a maioria dos cantos nesta demonstração deve ser levada a uma meia-esquadria das linhas azuis e a altura está diminuindo entre os cantos da esquerda para a direita porque eles estão conectados com ângulos crescentes; com valores intermediários, os cantos do lado esquerdo ou apenas um canto próximo às linhas azuis e os cantos do lado direito com uma extensão de esquadria (também com uma altura decrescente).

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

  // Clear canvas
  ctx.clearRect(0, 0, 150, 150);

  // Draw guides
  ctx.strokeStyle = "#09f";
  ctx.lineWidth = 2;
  ctx.strokeRect(-5, 50, 160, 50);

  // Set line styles
  ctx.strokeStyle = "#000";
  ctx.lineWidth = 10;

  // check input
  if (document.getElementById("miterLimit").value.match(/\d+(\.\d+)?/)) {
    ctx.miterLimit = parseFloat(document.getElementById("miterLimit").value);
  } else {
    alert("Value must be a positive number");
  }

  // Draw lines
  ctx.beginPath();
  ctx.moveTo(0, 100);
  for (i = 0; i < 24; i++) {
    var dy = i % 2 == 0 ? 25 : -25;
    ctx.lineTo(Math.pow(i, 1.5) \* 2, 75 + dy);
  }
  ctx.stroke();
  return false;
}
```

```
<table>
  <tr>
    <td><canvas id="canvas" width="150" height="150"></canvas></td>
    <td>
      Change the <code>miterLimit</code> by entering a new value below and
      clicking the redraw button.<br /><br />
      <form onsubmit="return draw();">
        <label>Miter limit</label>
        <input type="text" size="3" id="miterLimit" />
        <input type="submit" value="Redraw" />
      </form>
    </td>
  </tr>
</table>
```

```
document.getElementById("miterLimit").value = document
  .getElementById("canvas")
  .getContext("2d").miterLimit;
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Usando linhas tracejadas

`O método setLineDash` e a propriedade `lineDashOffset` especificam o padrão de traço para as linhas. O método `setLineDash` aceita uma lista de números que especificam distâncias para desenhar alternadamente entre uma linha e uma lacuna. Já a propriedade `lineDashOffset` define a distância até onde se deve iniciar a linha.

Neste exemplo, criaremos um efeito de formigas caminhando. É uma técnica de animação frequentemente usada em computação gráfica, pois ajuda o usuário a fazer uma distinção entre a borda e o plano de fundo animando a borda. Mais tarde neste tutorial, você aprenderá como fazer animações básicas.
```

<canvas id="canvas" width="110" height="110"></canvas>
```

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

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.setLineDash([4, 2]);
  ctx.lineDashOffset = -offset;
  ctx.strokeRect(10, 10, 100, 100);
}

function march() {
  offset++;
  if (offset > 16) {
    offset = 0;
  }
  draw();
  setTimeout(march, 20);
}

march();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

Gradients
---------

Just like any normal drawing program, we can fill and stroke shapes using linear and radial gradients. We create a `CanvasGradient` (en-US) object by using one of the following methods. We can then assign this object to the `fillStyle` or `strokeStyle` properties.

`createLinearGradient(x1, y1, x2, y2)` (en-US)

Creates a linear gradient object with a starting point of (`x1`, `y1`) and an end point of (`x2`, `y2`).

`createRadialGradient(x1, y1, r1, x2, y2, r2)` (en-US)

Creates a radial gradient. The parameters represent two circles, one with its center at (`x1`, `y1`) and a radius of `r1`, and the other with its center at (`x2`, `y2`) with a radius of `r2`.

For example:

```js
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
```

Once we've created a `CanvasGradient` object we can assign colors to it by using the `addColorStop()` method.

`gradient.addColorStop(position, color)` (en-US)

Creates a new color stop on the `gradient` object. The `position` is a number between 0.0 and 1.0 and defines the relative position of the color in the gradient, and the `color` argument must be a string representing a CSS `<color>`, indicating the color the gradient should reach at that offset into the transition.

You can add as many color stops to a gradient as you need. Below is a very simple linear gradient from white to black.

```js
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
lineargradient.addColorStop(0, "white");
lineargradient.addColorStop(1, "black");
```

### A `createLinearGradient` example

In this example, we'll create two different gradients. As you can see here, both the `strokeStyle` and `fillStyle` properties can accept a `canvasGradient` object as valid input.

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

  // Create gradients
  var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
  lingrad.addColorStop(0, "#00ABEB");
  lingrad.addColorStop(0.5, "#fff");
  lingrad.addColorStop(0.5, "#26C000");
  lingrad.addColorStop(1, "#fff");

  var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
  lingrad2.addColorStop(0.5, "#000");
  lingrad2.addColorStop(1, "rgba(0, 0, 0, 0)");

  // assign gradients to fill and stroke styles
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;

  // draw shapes
  ctx.fillRect(10, 10, 130, 130);
  ctx.strokeRect(50, 50, 50, 50);
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

The first is a background gradient. As you can see, we assigned two colors at the same position. You do this to make very sharp color transitions—in this case from white to green. Normally, it doesn't matter in what order you define the color stops, but in this special case, it does significantly. If you keep the assignments in the order you want them to appear, this won't be a problem.

In the second gradient, we didn't assign the starting color (at position 0.0) since it wasn't strictly necessary, because it will automatically assume the color of the next color stop. Therefore, assigning the black color at position 0.5 automatically makes the gradient, from the start to this stop, black.

| Screenshot | Live sample |
| --- | --- |
|  |  |

### A `createRadialGradient` example

In this example, we'll define four different radial gradients. Because we have control over the start and closing points of the gradient, we can achieve more complex effects than we would normally have in the "classic" radial gradients we see in, for instance, Photoshop (that is, a gradient with a single center point where the gradient expands outward in a circular shape).

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

  // Create gradients
  var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
  radgrad.addColorStop(0, "#A7D30C");
  radgrad.addColorStop(0.9, "#019F62");
  radgrad.addColorStop(1, "rgba(1, 159, 98, 0)");

  var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50);
  radgrad2.addColorStop(0, "#FF5F98");
  radgrad2.addColorStop(0.75, "#FF0188");
  radgrad2.addColorStop(1, "rgba(255, 1, 136, 0)");

  var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40);
  radgrad3.addColorStop(0, "#00C9FF");
  radgrad3.addColorStop(0.8, "#00B5E2");
  radgrad3.addColorStop(1, "rgba(0, 201, 255, 0)");

  var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90);
  radgrad4.addColorStop(0, "#F4F201");
  radgrad4.addColorStop(0.8, "#E4C700");
  radgrad4.addColorStop(1, "rgba(228, 199, 0, 0)");

  // draw shapes
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0, 0, 150, 150);
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

In this case, we've offset the starting point slightly from the end point to achieve a spherical 3D effect. It's best to try to avoid letting the inside and outside circles overlap because this results in strange effects which are hard to predict.

The last color stop in each of the four gradients uses a fully transparent color. If you want to have a nice transition from this to the previous color stop, both colors should be equal. This isn't very obvious from the code because it uses two different CSS color methods as a demonstration, but in the first gradient `#019F62 = rgba(1,159,98,1)`.

| Screenshot | Live sample |
| --- | --- |
|  |  |

Patterns
--------

In one of the examples on the previous page, we used a series of loops to create a pattern of images. There is, however, a much simpler method: the `createPattern()` method.

`createPattern(image, type)` (en-US)

Creates and returns a new canvas pattern object. `image` is a `CanvasImageSource` (en-US) (that is, an `HTMLImageElement` (en-US), another canvas, a `<video>` element, or the like. `type` is a string indicating how to use the image.

The type specifies how to use the image in order to create the pattern, and must be one of the following string values:

`repeat`

Tiles the image in both vertical and horizontal directions.

`repeat-x`

Tiles the image horizontally but not vertically.

`repeat-y`

Tiles the image vertically but not horizontally.

`no-repeat`

Doesn't tile the image. It's used only once.

We use this method to create a `CanvasPattern` (en-US) object which is very similar to the gradient methods we've seen above. Once we've created a pattern, we can assign it to the `fillStyle` or `strokeStyle` properties. For example:

```js
var img = new Image();
img.src = "someimage.png";
var ptrn = ctx.createPattern(img, "repeat");
```

**Nota:** Like with the `drawImage()` method, you must make sure the image you use is loaded before calling this method or the pattern may be drawn incorrectly.

### A `createPattern` example

In this last example, we'll create a pattern to assign to the `fillStyle` property. The only thing worth noting is the use of the image's `onload` handler. This is to make sure the image is loaded before it is assigned to the pattern.

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

  // create new image object to use as pattern
  var img = new Image();
  img.src = "canvas\_createpattern.png";
  img.onload = function () {
    // create pattern
    var ptrn = ctx.createPattern(img, "repeat");
    ctx.fillStyle = ptrn;
    ctx.fillRect(0, 0, 150, 150);
  };
}
```

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

Shadows
-------

Using shadows involves just four properties:

`shadowOffsetX = float` (en-US)

Indicates the horizontal distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.

`shadowOffsetY = float` (en-US)

Indicates the vertical distance the shadow should extend from the object. This value isn't affected by the transformation matrix. The default is 0.

`shadowBlur = float` (en-US)

Indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

`shadowColor = color` (en-US)

A standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

The properties `shadowOffsetX` and `shadowOffsetY` indicate how far the shadow should extend from the object in the X and Y directions; these values aren't affected by the current transformation matrix. Use negative values to cause the shadow to extend up or to the left, and positive values to cause the shadow to extend down or to the right. These are both 0 by default.

The `shadowBlur` property indicates the size of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0.

The `shadowColor` property is a standard CSS color value indicating the color of the shadow effect; by default, it is fully-transparent black.

**Nota:** Shadows are only drawn for `source-over` compositing operations.

### A shadowed text example

This example draws a text string with a shadowing effect.

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

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

  ctx.font = "20px Times New Roman";
  ctx.fillStyle = "Black";
  ctx.fillText("Sample String", 5, 30);
}
```

```
<canvas id="canvas" width="150" height="80"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

We will look at the `font` property and `fillText` method in the next chapter about drawing text.

Canvas fill rules
-----------------

When using `fill` (or `clip` and `isPointinPath` (en-US)) you can optionally provide a fill rule algorithm by which to determine if a point is inside or outside a path and thus if it gets filled or not. This is useful when a path intersects itself or is nested.

Two values are possible:

`nonzero`

The non-zero winding rule, which is the default rule.

`evenodd`

The even-odd winding rule.

In this example we are using the `evenodd` rule.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.beginPath();
  ctx.arc(50, 50, 30, 0, Math.PI \* 2, true);
  ctx.arc(50, 50, 15, 0, Math.PI \* 2, true);
  ctx.fill("evenodd");
}
```

```
<canvas id="canvas" width="100" height="100"></canvas>
```

```
draw();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

* « Previous
* Next »


ServiceWorkerGlobalScope.clients - APIs da Web

ServiceWorkerGlobalScope.clients
================================

A propriedade somente-leitura **`clients`** da interface `ServiceWorkerGlobalScope` (en-US) retorna os objetos dos `Clients` (en-US) associatos ao *service worker*.

Sintaxe
-------
```

swClients = self.clients
```

### Valor

O objeto `Clients` (en-US) associado ao *service worker* específico.

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

| Specification |
| --- |
| Service Workers # service-worker-global-scope-clients |

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

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

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

* Using Service Workers (en-US)
* Service workers basic code example
* Is ServiceWorker ready?
* `Promise`
* Using web workers (en-US)


Node.replaceChild - APIs da Web

Node.replaceChild
=================

Sumário
-------

Substitui o elemento filho especificado por outro.

Sintaxe
-------
```

replacedNode = parentNode.replaceChild(newChild, oldChild);
```

* `newChild` é o novo elemento que será inserido no lugar do `oldChild`. Se já existir no DOM, será removido primeiro para depois ser inserido.
* `oldChild` é o elemento existente que será substituído.
* `replacedNode` é elemento substituído. É o mesmo elemento que oldChild.
Exemplo
-------

```js
// <div>
// <span id="childSpan">foo bar</span>
// </div>

// Cria um novo elemento vazio
// sem ID, atributos ou conteúdo
var sp1 = document.createElement("span");

// Adiciona um ID 'newSpan' para o elemento
sp1.setAttribute("id", "newSpan");

// Adiciona contéudo para o elemento
var sp1_content = document.createTextNode("new replacement span element.");

// Coloca o conteúdo no elemento
sp1.appendChild(sp1_content);

// Procura o elemento que será substituído
var sp2 = document.getElementById("childSpan");
var parentDiv = sp2.parentNode;

// Substituí o elemento que já existe (sp2) por o novo elemento (sp1)
parentDiv.replaceChild(sp1, sp2);

// resultado:
// <div>
// <span id="newSpan">new replacement span element.</span>
// </div>
```

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

* DOM Level 1 Core: replaceChild
* DOM Level 2 Core: replaceChild
* DOM Level 3 Core: replaceChild
Veja também
-----------

* `Node.removeChild`


Node.baseURI - APIs da Web

Node.baseURI
============

Resumo
------

A propriedade somente leitura **`Node.baseURI`** retorna a URL base absoluta de um nó.

A URL base é usada para resolver URLs relativas quando o navegador precisa obter uma URL absoluta, por exemplo, quando processa o atributo `src` do elemento HTML `<img>` ou o atributo `xlink:href` do XML.

No caso comum, a URL base é simplesmente a localização do documento, mas ela pode ser afetada por vários fatores, incluindo o elemento `<base>` em HTML e o atributo xml:base (en-US) em XML.

Sintaxe
-------
```

var baseURI = node.baseURI;
```

* `baseURI` é uma `DOMString` que representa a URL base do `Node` especificado. Pode ser `null` caso não consiga obter uma URL absoluta.
* `node.baseURI` é somente leitura.
* `node.baseURI` pode mudar com o tempo (ver abaixo).
Detalhes
--------

### A URL base de um documento

É a URL base de um *documento* padrão ao endereço do documento ( como exibido pelo navegador e disponível em `window.location` ), mas pode mudar o padrão:

* Quando uma tag HTML `<base>` é encontrada no documento;
* Quando esse é um novo documento creado dinamicamente.

Veja a seção URLs base do padrão HTML para mais detalhes.

Você pode usar ``document`.baseURI` para obter a URL base de um documento. Note que a obtenção da URL base para um documento pode retornar diferentes URLs ao longo do tempo se as tags `<base>` ou a localização do documento mudarem.

### A URL base de um elemento

A URL base de um elemento em HTML é, normalmente, igual a URL base do documento onde o nó está.

Se o documento contém atributos `xml:base` (en-US) ( que você não deve fazer em documento HTML), o `element.baseURI` recebe os atributos `xml:base` dos elementos pai into account when computing the base URL. Veja xml:base (en-US) para mais detalhes.

Você pode usar ``element`.baseURI` para obter a URL base de um elemento.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-baseuri① |

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

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

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

* Elemento `<base>` (HTML)
* Atributo `xml:base` (en-US) (Documentos XML)
* `Node.baseURIObject` (en-US) – uma variante desta API para complementos da Mozilla e código interno. Retorna a URL base como uma `nsIURI`


Node.cloneNode() - APIs da Web

Node.cloneNode()
================

O método **`Node.cloneNode()`** duplica um elemento node (nó) da estrutura de um documento DOM. Ele retorna um clone do elemento para o qual foi invocado.

Syntax
------
```

var dupNode = node.cloneNode(deep);
```

*node*

O elemento node (nó) a ser clonado 'duplicado'.

*dupNode*

O novo elemento node (nó) resultado da clonagem do elemento node.

*deep Optional [1]*

true se os elementos filhos do nó que está sendo clonado devem ser clonados juntos, ou false para clonar apenas o nó específico dispensando, assim, qualquer elemento DOM filho. Veja os exemplos abaixo.

**Nota:** Na especificação do DOM4 (implementado no Gecko 13.0), o argumento `deep` é opcional. Se omitido, por padrão, o método age como se o valor de deep fosse setado como true durante a sua execução. Para criação de clones superficiais, o argumento `deep` deve ser setado como `false`.

Este comportamento foi alterado na última especificação. Se omitido o argumento deep, o método irá interpretar o valor de deep como se fosse false. Embora ele continue opcional, é recomendado que você sempre observe o argumento deep para fins de compatibilidade anterior e posterior. Com o Gecko 28.0), foi advertido aos desenvolvedores para não omitirem o argumento. Iniciado com o Gecko 29.0), um clone superficial é o padrão ao invés de um clone aprofundado.

Exemplo
-------

```js
<div id="paragrafos">
  <p>Texto parágrafo</p>
</div>;

//Obtém o elemento div
var div_p = document.getElementById("paragrafos");

//Obtém o primeiro filho do elemento div
var p = div_p.firstChild;

//Clona o elemento, no caso, um parágrafo
var p_clone = p.cloneNode(true);

//Adiciona o clone do elemento <p> ao elemento <div>
div_p.appendChild(p_clone);
```

Notas
-----

A clonagem de um elemento node copia todos os seus atributos e valores. Porém, não tem o mesmo comportamento em relação aos "event listeners".

O elmento node resultante da ação de clonagem não faz parte da estruturam DOM do documento até que ele seja adicionado utilizando o método appendChild() ou outro similar, conforme exemplo acima.

Se o argumento (deep) for setado como false, os nós filhos do elemento node clonado não serão clonados juntos, assim como os respectivos textos.

Se o argumento (deep) for setado como true, os nós filhos, toda a árvore DOM do elemento clonado, será clonada junto.

**Aviso:** **Cuidado:** `cloneNode()` pode duplicar IDs em um documento.

Se o elemento node (nó) clonado tiver uma ID e o novo elemento node resultante da clonagem for ser inserido no mesmo documento, a ID de um dos nós deve ser alterada para que observem o princípio de unicidade. Em outras palavras, um mesmo documento não pode ter elementos com IDs iguais. Se for o caso de trabalhar com manipulação de elementos DOM através do atributo "name", tome cuidado em observá-lo.

Clonagem de node (nó) para um documento diferente, use o seguinte método: `Document.importNode()`.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-clonenode① |

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

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


Node.previousSibling - APIs da Web

Node.previousSibling
====================

Resumo
------

Retorna o nó que precede o nó especificado na lista de childNodes do nó pai, retorna null se o nó especificado é o primeiro desta lista.

Sintaxe
-------
```

previousNode = node.previousSibling;
```

Exemplo
-------

```js
// <a><b1 id="b1"/><b2 id="b2"/></a>

alert(document.getElementById("b1").previousSibling); // null
alert(document.getElementById("b2").previousSibling.id); // "b1"
```

Notas
-----

 Navegador baseados na engine Gecko inserem nós de texto no documento para representar espaços em branco na marcação do fonte.
 Portanto um nó obtido, por exemplo, usando `Node.firstChild` ou `Node.previousSibling` pode fazer referência a um
 espaço em banco ao invés do elemento que o autor pretendia obter.

 Veja Whitespace in the DOM (en-US) e
 W3C DOM 3 FAQ: Why are some Text nodes empty?
 Para mais informações.

Para navegar no sentido contrário da lista de nós filhos use Node.nextSibling.

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

* DOM Level 1 Core: previousSibling
* DOM Level 2 Core: previousSibling
* DOM Level 3 Core: previousSibling


Node.textContent - APIs da Web

Node.textContent
================

A propriedade **`textContent`** da interface `Node` representa o conteúdo de texto de um nó e dos seus descendentes.

**Nota:** `textContent` e `HTMLElement.innerText` são facilmente confundidos, mas os dois possuem importantes diferenças entre sí.

Sintaxe
-------

```js
var text = Node.textContent;
Node.textContent = string;
```

### Valor de retorno

Uma `String` ou `null`

Descrição
---------

Ao obter valores desta propriedade:

* Se o nó for um document (en-US), um DOCTYPE, ou uma notation, o `textContent` retornará `null`. (Para se obter todo o texto e os dados CDATA (en-US) do documento inteiro, você poderá usar `document.documentElement.textContent`.)
* Se o nó for uma seção CDATA (en-US), comentário, instrução de processamento, ou um text node (en-US), o `textContent` retornará o texto dentro do nó, i.e., o `Node.nodeValue` (en-US).
* Para outros tipos de nó, o `textContent` retornará a concatenação `textContent` de cada nó filho, exceto comentários e instruções de processamento. Essa é uma string vazia se o nó não tiver filhos.

Definir valores `textContent` em um nó, remove todos os nós filhos e os substituem por um único nó de texto cujo o valor é a string inserida.

### Diferenças para o innerText

Não fique confuso pelas diferenças entre o `Node.textContent` e o `HTMLElement.innerText`. Apesar dos nomes parecerem similares, eles possuem importantes diferenças:

* `textContent` obtém o conteúdo de todos os elementos, incluindo os elementos `<script>` e `<style>`. por outro lado, o `innerText` mostra apenas os elementos para "leitura humana".
* `textContent` retorna todos os elementos de um nó. Por outro lado, o `innerText` é ciente da estilização e não retorna elementos de texto "escondidos". Além disso, como o `innerText` leva em consideração os estilos CSS, a leitura do valor de `innerText` dispara um reflow para assegurar a atualização dos estilos computados. (Reflows podem ser computacionalmente caros, e devem ser evitados quando for possível.)
* ao contrário do `textContent`, alterar o `innerText` no Internet Explorer (versão 11 e anteriores) remove os nós filhos do elemento e, *destroi permanentemente* todos os nós de texto descendentes. Isso torna impossível inserir novamente os nós em qualquer outro elemento ou no mesmo elemento.
### Diferenças para o innerHTML

O `Element.innerHTML` retorna HTML, Como seu próprio nome indica. As vezes as pessoas usam o `innerHTML` para obter ou escrever textos dentro de um elemento, mas o `textContent` possui melhor performance pois seus valores não são analisados como HTML. Além do mais, utilizar `textContent` pode prevenir ataques XSS (en-US).

Exemplos
--------

Dado o seguinte fragmento HTML:

```html
<div id="divA">Isto é<span>algum</span> texto!</div>
```

... Você pode usar `textContent` para obter o conteúdo de texto do elemento:

```js
let text = document.getElementById("divA").textContent;
// Agora a variável de texto é: 'Isto é algum texto!'
```

... Ou definir o conteúdo de texto do elemento:

```js
document.getElementById("divA").textContent = "Este texto é diferente!";
// O HTML de divA agora é:
// <div id="divA">Este texto é diferente!</div>
```

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

| Specification |
| --- |
| DOM Standard # dom-node-textcontent |

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

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

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

* `HTMLElement.innerText`
* `Element.innerHTML`
* More on differences between `innerText` and `textContent` (blog post)


Node.contains - APIs da Web

Node.contains
=============

Sumário
-------

Indica se um nó é um descendente de um dado nó.

Sintaxe
-------
```

node.contains( otherNode )
```

* `node` é o nó que está sendo comparado.
* `otherNode` é o nó contra o qual está sendo comparado.

O valor de retorno é `true` se `otherNode` é um descendente de um nó ou o próprio nó. Caso contrário o valor de retorno é `false`.

Exemplo
-------

Esta função verifica se um elemento está no corpo da página. As `contains` is inclusive and determining if the body contains itself isn't the intention of `isInPage` this case explicitly returns `false`.

```js
function isInPage(node) {
  return node === document.body ? false : document.body.contains(node);
}
```

* `node` é o nó que desejamos verificar se está no `<body>`.
Especificações
--------------

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

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

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

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

* `Node.hasChildNodes` (en-US)


Node.removeChild - APIs da Web

Node.removeChild
================

Sumário
-------

Remove um nó filho do DOM. Devolve o nó removido.

Sintaxe
-------
```

var filhoRemovido = elemento.removeChild(filho);
elemento.removeChild(filho);
```

* `filho` é o nó filho a ser removido do DOM.
* `elemento` é o nó pai de `filho`.
* `filhoRemovido` contém uma referência ao nó filho removido. `filhoRemovido` === `filho`.

O nó filho removido ainda existe em memória, mas não é mais parte do DOM. Você pode reutilizar o nó removido mais tarde no seu código por meio da referência `filhoRemovido`.

Se `filho` não for um filho do nó `elemento`, o método lança uma exceção. Isto também acontecerá se `filho` era, de fato, um filho de `elemento` no momento da chamada, mas foi removido por um manipulador de eventos invocado enquanto o elemento estava sendo removido (por exemplo, blur).

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

<!--Código HTML de exemplo-->

<div id="topo" align="center">
  <div id="interno"></div>
</div>
```

```js
// Removendo um elemento específico quando se conhece seu pai
var d = document.getElementById("topo");
var d_interno = document.getElementById("interno");
var noRemovido = d.removeChild(d_interno);
```

```js
// Removendo um elemento específico sem precisar especificar seu pai
var no = document.getElementById("interno");
if (no.parentNode) {
  no.parentNode.removeChild(no);
}
```

```js
// Removendo todos os nós filhos de um elemento
var elemento = document.getElementById("topo");
while (elemento.firstChild) {
  elemento.removeChild(elemento.firstChild);
}
```

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

* DOM Level 1 Core: removeChild
* DOM Level 2 Core: removeChild
* DOM Level 3 Core: removeChild
Veja também
-----------

* `Node.replaceChild`
* `Node.parentNode`


Node.firstChild - APIs da Web

Node.firstChild
===============

**`Node.firstChild`** é uma propriedade do tipo somente leitura que retorna o node (nó) do primeiro elemento filho de uma árvore DOM ou null no caso do elemento não ter filhos (children).

Syntax
------
```

var childNode = node.firstChild;
```

**node:** elemento node (nó pai) de referência para busca do seu primeiro filho (firstChild) considerada a estrutura DOM.

**childNode:** elemento node (nó filho) considerado como primeiro filho (firstChild) de node (pai).

Descrição
---------

childNode é uma referência para o primeiro filho (node) de uma estrutura DOM, um node (nó) que não tem filhos retornará null.

Exemplo
-------

Este exemplo demonstra o uso do firstChild e como os espaços em branco "whitespace" de um node (nó) podem interferir.

```html
<p id="para-01">
  <span>First span</span>
</p>

<script type="text/javascript">
 var p01 = document.getElementById("para-01");
 console.log(p01.firstChild.nodeName);
</script>
```

No exemplo acima, o console.log() deverá exibir '#text' porque o nó de texto inserido mantém espaços em branco 'whitespace' entre a tag <p id="para-01"> e a tag <span>. Qualquer espaço em branco poderá causar '#text'.

**Nota:** "Tabs" também podem causar esse comportamento.

Se os espaços em branco for removidos do código, o '#text' não será mais considerado e a tag <span> se tornará o primeiro filho firstChild do parágrafo, conforme exemplo abaixo.

```html
<p id="para-01"><span>First span</span></p>

<script type="text/javascript">
 var p01 = document.getElementById("para-01");
 console.log(p01.firstChild.nodeName);
</script>
```

Agora o console.log() irá exibir 'SPAN'.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-firstchild① |

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

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


Node.childNodes - APIs da Web

Node.childNodes
===============

A propriedade somente leitura **`Node.childNodes`** retorna uma *coleção viva* de nós filhos de um dado elemento.

Sintaxe
-------
```

var listaNos = noReferencia.childNodes;
```

*listaNos é uma coleção ordenada de objetos node que são filhos do elemento corrente. Se o elemento não tem filhos, então listaNos não contém nenhum nó.*

A listaNos é uma variável que armazena a lista de nós de childNodes. O tipo dessa lista é `NodeList`.

Exemplo
-------

```js
// parg é uma referência de objeto a um elemento <p>

if (parg.hasChildNodes()) {
  // Primeiramente verificamos se o objeto não está vazio, se o objeto tem nós filhos
  var filhos = parg.childNodes;

  for (var i = 0; i < filhos.length; i++) {
    // fazer algo com cada filho em filhos[i]
    // NOTE: A lista é viva - adicionar ou remover filhos altera a lista
  }
}
```

---

```js
// Esta é uma forma para remover todos os filhos de um nó
// box é uma referência de objeto para um elemento com filhos

while (box.firstChild) {
  // A lista é VIVA, então ela re-indexará a cada chamada
  box.removeChild(box.firstChild);
}
```

Notas
-----

Os itens na coleção de nós são objetos, não strings. Para recuperar dados dos objetos dos nós, você deve usar suas propriedades (e.g., `noReferencia.childNodes[1].nodeName` para recuperar o nome, etc.).

O objeto `document` tem 2 filhos: a declaração Doctype declaration e o elemento raiz, tipicamente referido como `documentElement`. (Em documentos (X)HTML este é o elemento `HTML`)

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-childnodes① |

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

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

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

* `Node.firstChild`
* `Node.lastChild`
* `Node.nextSibling`
* `Node.previousSibling`
* `ParentNode.children` (en-US)


Node.parentNode - APIs da Web

Node.parentNode
===============

**`Node.parentNode`** é uma propriedade DOM somente leitura que retorna o nó (node) parente de um Node referenciado na árvore DOM. É extremamente aconselhável que você conheça a estrutura DOM para um melhor estudo e aprendizado.

Syntax
------
```

parentNode = node.parentNode
```

`parentNode` é o node parente do node referenciado. O parente de um elemento é um Element node, um Document node, ou um DocumentFragment node. Será muito complicado entender tudo isso sem conhecer a estrutura DOM e seus Elements.

Exemplo
-------

```js
// Exemplo de como obter um elemento pai
parente = node.parentNode; // Retorna o elemento pai

// Obtém o primeiro <li> de uma lista
var li = document.getElementsById("li-first");
// A partir do <li> obtido, obtém o element <ul>
var ul = li.parentNode;

// Estrutura com parágrafos dentro de uma div
var p = document.getElementsByTagName("p");
var div = p[0].parentNode;

if (node.parentNode) {
  // remove um node da árvore (estrutura) DOM, a menos que
  // ele já não exista não estrutura
  node.parentNode.removeChild(node);
}
```

Notas
-----

`Document` e `DocumentFragment` nodes (en-US) nunca podem ter um node parent, sendo assim `parentNode` sempre retornará `null`. Também retornará null se o node já tiver sido criado e não ainda não estiver anexado à estrutura DOM.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-parentnode① |

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

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

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

* `Node.firstChild`
* `Node.lastChild`
* `Node.childNodes`
* `Node.nextSibling`
* `Node.previousSibling`
* `Node.removeChild`


Node.lastChild - APIs da Web

Node.lastChild
==============

**`Node.lastChild`** é uma propriedade do tipo somente leitura (read-only) que retorna o último elemento filho (node) de uma estrutura DOM. Se seu parentNode for um Element, ele retornará um Element node, um text node, ou um comment node. Retornará null se o elemento de referência não tiver elementos filhos child. É extremamente recomendável que você conheça a estrutura DOM para um melhor aprendizado e entendimento.

Syntax
------
```

var last_child = element.lastChild
```

Exemplo
-------

```js
// Obtém um elemento <ul>
var ul = document.getElementById("lista");

// Obtém o último <li> pertencente a estrutura <ul> obtida
var li_last = ul.lastChild;
```

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-lastchild① |

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

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


Node.insertBefore - APIs da Web

Node.insertBefore
=================

O método **`Node.insertBefore()`** insere um nó antes do nó de referência como um filho de um nó pai especificado. Se o filho especificado for uma referência a um nó existente no documento, `insertBefore()` o moverá de sua posição atual para a nova posição (não há necessidade de remover o nó de seu nó pai antes de anexá-lo a outro nó).

Isso significa que um nó não pode estar em dois pontos do documento simultaneamente. Portanto, se o nó já tiver um pai, o nó será removido pela primeira vez e inserido na nova posição. O `Node.cloneNode()` pode ser usado para fazer uma cópia do nó antes de anexá-lo ao novo pai. Note que as cópias feitas com `cloneNode()` não serão automaticamente mantidas em sincronia.

Se o nó de referência for `null`, o nó especificado será incluído no final da lista de filhos do nó pai especificado.

Se o filho especificado for um `DocumentFragment`, todo o conteúdo do `DocumentFragment` será movido para a lista de filhos do nó pai especificado.

Sintaxe
-------
```

var elementoInserido = elementoPai.insertBefore(novoElemento, elementoDeReferencia);
```

* `elementoInserido` O nó sendo inserido, que é `novoElemento`
* `elementoPai` Pai do nó recentemente inserido.
* `novoElemento` O nó a ser inserido.
* `elementoDeReferencia` O nó antes do qual o `novoElemento` será inserido.

Se *elementoDeReferencia* for `null`, *novoElemento* será inserido no fim da lista de nós filhos.

**Nota:** `elementoDeReferencia` não é um parâmetro opcional - você deve passar explicitamente um `Node` ou `null`. Deixar de fornecer ou passar valores inválidos pode ter comportamento diferente em diferentes versões de navegadores.

### Return value

O valor retornado é o filho incluído, exceto quando `newNode` é um `DocumentFragment`, caso em que o `DocumentFragment` vazio é retornado.

Exemplo
-------

```html
<div id="elementoPai">
  <span id="elementoFilho">foo bar</span>
</div>

<script>
 // Cria um novo elemento <span> vazio
 var sp1 = document.createElement("span");

 // Guarda a referência do elemento atraś do qual nos queremos inserir o novo elemento
 var sp2 = document.getElementById("elementoFilho");
 // Guarda a referência do elemento pai
 var divPai = sp2.parentNode;

 // Insere o novo elemento no DOM antes de sp2
 divPai.insertBefore(sp1, sp2);
</script>
```

Não existe um método `insertAfter`. Mas ele pode ser emulado combinando o método `insertBefore` com `nextSibling` (en-US).

No exemplo anterior, `sp1` poderia ser inserido após `sp2` desta forma:
```

divPai.insertBefore(sp1, sp2.nextSibling);
```

Se `sp2` não possuir um próximo nó, significa que ele deve ser o último filho — `sp2.nextSibling` retorna `null`, e `sp1` é inserido ao fim da da lista de nós filhos (logo após sp2).

Exemplo 2
---------

Inserir um elemento antes do primeiro nó filho, usando a propriedade firstChild (en-US).

```js
// Guarda a referêncis do elemento no quela nóe queremos inserir o novo nó
var elementoPai = document.getElementById("elementoPai");
// Guarda a referência do primeiro filho
var primeiroFilho = elementoPai.firstChild;

// Cria um novo elemento
var novoElemento = document.createElement("div");

// Insere o novo elemento antes do primeiro filho
elementoPai.insertBefore(novoElemento, primeiroFilho);
```

Quando o elemento não possui o primeiro filho, então `firstChild` é `null`. O elemento ainda será inserido no pai, mas após o último filho. Pois se o elemento pai não possui primeiro filho, ele também não possui o último filho. Conseqüentemente, o novo elemento será o único elemento após a inserção.

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

| Specification |
| --- |
| DOM Standard # dom-node-insertbefore |

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

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


Node.nextSibling - APIs da Web

Node.nextSibling
================

Resumo
------

Retorna o nó seguinte ao especificado dentro do lista de filhos do seu pai(`childNodes`), ou `null` se o nó especificado for o último nó da lista.

Sintaxe
-------
```

proximoNo = no.nextSibling
```

Exemplo
-------

```html
<div id="div-01">Aqui esta a div-01</div>
<div id="div-02">Aqui esta a div-02</div>

<script type="text/javascript">
 var el = document.getElementById("div-01").nextSibling;

 document.write("<p>Nós irmãos de div-01</p><ol>");

 while (el) {
 document.write("<li>" + el.nodeName + "</li>");
 el = el.nextSibling;
 }

 document.write("</ol>");
</script>

<!--
 O seguinte texto será escrito na página quando ela carregar:

 Nós irmãos de div-01

 1. #text
 2. DIV
 3. #text
 4. SCRIPT
 5. P
 6. OL
-->
```

No exemplo acima, pode ser visto que nós `#text` são inseridos no DOM onde espaços em branco aparecem na marcação entre as tags (ex.: após o fechamento da tag de um elemento e antes da abertura da próxima tag). Nenhum espaço em branco é criado entre elementos inseridos pelo comando `document.write`.

A possível inclusão de nós de texto no DOM deve ser permitida quando navegar pelo mesmo usando `nextSibling`.

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-nextsibling① |

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

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


Node.appendChild - APIs da Web

Node.appendChild
================

Resumo
------

Adiciona um nó ao final da lista de filhos de um nó pai especificado. Se o nó já existir no documento, ele é removido de seu nó pai atual antes de ser adicionado ao novo pai.

Sintaxe
-------
```

var filho = elemento.appendChild(filho);
```

* `elemento` é o elemento (en-US) pai.
* `filho` é o nó a ser adicionado como filho de `elemento`. Também é devolvido.
Descrição
---------

O método `appendChild` devolve uma referência ao nó adicionado.

Exemplo
-------

```js
// Cria um novo elemento de parágrafo e adiciona-o ao final do documento
var p = document.createElement("p");
document.body.appendChild(p);
```

Notas
-----

Se `filho` é uma referência a um nó existente no documento, `appendChild` vai movê-lo de sua posição atual para a nova posição (i.e, não é necessário remover o nó de seu pai atual antes de adicioná-lo a outro nó).

Isso também significa que um nó não pode estar em dois lugares do documento ao mesmo tempo. Assim, se o nó já tem um pai, ele é primeiro removido para, *só então*, ser adicionado na nova posição.

Você pode usar o método `Node.cloneNode` para criar uma cópia do nó antes de adicioná-lo ao novo pai. (Note que cópias feitas com o método `cloneNode` **não** serão mantidas sincronizadas automaticamente)

Este método não permite mover nós entre documentos diferentes. Se você quiser adicionar um nó de um documento diferente (por exemplo para mostrar o resultado de uma requisição AJAX), você precisa primeiro usar o método `document.importNode`.

`appendChild()` é um dos métodos fundamentais da programação para a web usando o DOM. O método `appendChild()` insere um novo nó na estrutura do DOM de um documento, e é a segunda parte do processo criar-e-adicionar tão importante na construção de páginas web programaticamente.

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

* DOM Level 3 Core: appendChild
Ver também
----------

* `Node.removeChild`
* `Node.replaceChild`
* `Node.insertBefore`
* `Node.hasChildNodes` (en-US)


Node.isConnected - APIs da Web

Node.isConnected
================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

* Learn more
* See full compatibility
* Report feedback
A propriedade somente-leitura **`isConnected`** da interface `Node` retorna um boleano indicando se um nó está conectado (direta ou indiretamente) ao contexto do objeto, por exemplo o objeto `Document` no caso da DOM normal, ou o `ShadowRoot` (en-US) no caso de uma shadow DOM.

Sintaxe
-------
```

var isItConnected = nodeObjectInstance.isConnected
```

### Retorno

Um `Boolean` (en-US) que é `true` se o nó está conectado ao contexto relevante do objeto, e `false` se não está.

Examples
--------

### Standard DOM

Um exemplo em um DOM padrão:

```js
let test = document.createElement("p");
console.log(test.isConnected); // Returns false
document.body.appendChild(test);
console.log(test.isConnected); // Returns true
```

### Shadow DOM

Um exemplo em um Shadow DOM:

```js
// Cria um raíz Shadow
var shadow = this.attachShadow({ mode: "open" });

// Cria um CSS para aplicar a Shadow DOm
var style = document.createElement("style");
console.log(style.isConnected); // retorna false

style.textContent = `
.wrapper {
 position: relative;
}

.info {
 font-size: 0.8rem;
 width: 200px;
 display: inline-block;
 border: 1px solid black;
 padding: 10px;
 background: white;
 border-radius: 10px;
 opacity: 0;
 transition: 0.6s all;
 positions: absolute;
 bottom: 20px;
 left: 10px;
 z-index: 3
}
`;

// Anexa a estilização criada a Shadow DOM.

shadow.appendChild(style);
console.log(style.isConnected); // retorna true
```

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

| Specification |
| --- |
| DOM Standard # ref-for-dom-node-isconnected① |

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

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