APIs Nativas do Navegador com JavaScript Que Tornam Sites Muito Mais Poderosos

Published on: 2026-01-16
Post image
pt apis-nativas-do-navegador javascript-moderno web-apis-javascript desenvolvimento-frontend recursos-do-navegador programacao-web sites-interativos frontend-moderno tecnologia-web javascript-avancado

As APIs da Web formam um conjunto de interfaces que permitem que páginas e aplicações no navegador acessem recursos do dispositivo e do próprio ambiente do browser. Em vez de depender apenas de HTML e CSS, essas APIs liberam capacidades como armazenamento local, áudio avançado, comunicação em tempo real, leitura de sensores e integração com recursos do sistema.

O tema também inclui limites importantes: alguns recursos exigem permissões, outros dependem do navegador e do sistema operacional, e há casos em que a Web não alcança o mesmo acesso de um aplicativo nativo. Com uma visão organizada, fica mais claro quando usar cada API e como escrever um código seguro e previsível.

RFID, NFC e a diferença entre hardware dedicado e API Web

RFID (Identificação por Radiofrequência) é uma tecnologia em que etiquetas (tags) se comunicam por rádio com leitores para identificar objetos. Em celulares, o parente mais próximo é o NFC (Near Field Communication), que opera a curta distância e é comum em pagamentos por aproximação e leitura de tags. No mundo Web, o acesso direto a RFID “genérico” não é um padrão amplo, porque leitores podem exigir drivers e permissões fora do alcance do navegador. Por isso, RFID costuma ser feito por hardware específico e software nativo (Android e iOS) ou por leitores USB com integração via desktop.

Quando um leitor RFID se apresenta ao sistema como dispositivo USB, o navegador normalmente não “enxerga” esse leitor automaticamente como uma fonte de tags. Em alguns cenários, a leitura vira “entrada de teclado” (HID), onde o leitor “digita” um código em um campo de texto, o que funciona sem API especial, mas com menos controle. Em aplicações mais robustas, entram integrações nativas (apps) ou aplicações desktop que conversam com o leitor e repassam dados para a Web. Já o NFC tem uma API Web em alguns ambientes, permitindo leitura e escrita de mensagens NDEF (NFC Data Exchange Format).

Web NFC API para leitura de tags NFC

A Web NFC API é uma interface que permite ler e, em alguns casos, escrever em tags NFC usando o navegador. O objeto central é o NDEFReader, que inicia uma varredura e dispara eventos quando uma tag é aproximada. Por envolver aproximação e dados do mundo físico, normalmente exige contexto seguro (HTTPS) e permissões do usuário. A disponibilidade varia bastante entre navegadores e sistemas, então é comum ter lógica de detecção e caminhos alternativos.

O exemplo a seguir mostra uma leitura básica de mensagens NDEF, registrando no console os dados recebidos. Ele ilustra o fluxo típico: instanciar o leitor, iniciar o scan e reagir ao evento de leitura. Em implementações reais, costuma existir tratamento de erros, cancelamento e extração detalhada de registros (records) dentro da mensagem. Também é comum registrar no estado da aplicação quando o scan está ativo para evitar chamadas duplicadas.

// Leitura básica de NFC com Web NFC (experimental)
async function iniciarLeituraNFC() {
  if (!("NDEFReader" in window)) {
    console.error("Web NFC indisponível neste navegador/ambiente.");
    return;
  }

  try {
    const leitor = new NDEFReader();
    await leitor.scan();

    leitor.onreading = (evento) => {
      console.log("Mensagem NDEF recebida:", evento.message);

      // Exemplo: iterar pelos registros NDEF
      for (const registro of evento.message.records) {
        console.log("Registro:", {
          tipo: registro.recordType,
          midia: registro.mediaType,
          id: registro.id
        });
      }
    };

    leitor.onreadingerror = () => {
      console.error("Falha ao ler a tag NFC. Aproximação ou tag incompatível.");
    };
  } catch (erro) {
    console.error("Erro ao iniciar scan NFC:", erro);
  }
}

iniciarLeituraNFC();

Payment Request API para fluxo de pagamento padronizado

A Payment Request API oferece uma forma padronizada de apresentar opções de pagamento, sem que o site precise construir toda a experiência de checkout do zero. Ela não cria um “novo método” de pagamento; ela organiza como o navegador coleta e devolve dados de pagamento já existentes. Isso pode reduzir atrito, pois o navegador pode reutilizar informações salvas, como cartões e endereços, quando suportado. Por segurança e consistência, o navegador controla a interface visual do prompt de pagamento.

O fluxo é: declarar métodos suportados, declarar detalhes (como total) e chamar request.show(). Ao final, o código recebe um paymentResponse e confirma a finalização com complete(). Em produção, a validação e a cobrança real acontecem no servidor, e o retorno do servidor determina se a finalização será “success” ou “fail”. O exemplo abaixo mantém o foco na estrutura e no ciclo de vida da API.

// Exemplo básico de Payment Request API
async function solicitarPagamento() {
  if (!("PaymentRequest" in window)) {
    console.error("Payment Request API não suportada neste navegador.");
    return;
  }

  const instrumentosSuportados = [
    { supportedMethods: "basic-card" }
  ];

  const detalhesPagamento = {
    total: {
      label: "Total",
      amount: { currency: "USD", value: "10.00" }
    }
  };

  try {
    const requisicao = new PaymentRequest(instrumentosSuportados, detalhesPagamento);
    const resposta = await requisicao.show();

    // Em um cenário real, aqui ocorreria a validação no servidor e a cobrança.
    await resposta.complete("success");
    console.log("Pagamento concluído com sucesso.");
  } catch (erro) {
    console.error("Pagamento cancelado ou falhou:", erro);
  }
}

solicitarPagamento();

Push API para mensagens enviadas do servidor ao navegador

A Push API permite que uma aplicação Web receba mensagens “empurradas” por um servidor, mesmo quando a página não está em primeiro plano. Na prática, ela costuma ser usada junto com Service Worker, que é um script em segundo plano capaz de reagir a eventos de push e exibir notificações. O navegador gerencia uma inscrição (subscription) por meio do PushManager, e o servidor envia mensagens para um endpoint associado a essa inscrição. Como envolve interrupções e permissão, o usuário precisa autorizar notificações.

O trecho a seguir mostra a checagem de suporte e a solicitação de permissão de notificação. Para um fluxo completo, seria necessário registrar um Service Worker, obter a inscrição via pushManager.subscribe() e enviar a subscription ao servidor. Também é comum lidar com revogação de permissão e com revalidação periódica da inscrição. O exemplo mantém o foco nos pontos mínimos para iniciar corretamente.

// Checagem básica de suporte e permissão para Push/Notificações
function configurarPushBasico() {
  if (!("PushManager" in window)) {
    console.error("Push API não suportada neste navegador.");
    return;
  }

  if (!("Notification" in window)) {
    console.error("Notifications API não suportada neste navegador.");
    return;
  }

  Notification.requestPermission().then((permissao) => {
    if (permissao === "granted") {
      console.log("Permissão concedida. Assinatura (subscription) viria aqui.");
    } else {
      console.log("Permissão negada ou padrão.");
    }
  });
}

configurarPushBasico();

Web Speech API: síntese de fala e reconhecimento de voz

A Web Speech API reúne recursos relacionados a voz, incluindo síntese de fala (texto para voz) e, em alguns navegadores, reconhecimento de fala (voz para texto). A síntese costuma ser exposta via SpeechSynthesis e SpeechSynthesisUtterance, permitindo configurar idioma, velocidade e volume. Já o reconhecimento pode variar por navegador e frequentemente aparece com prefixos, como webkitSpeechRecognition. Por envolver microfone e processamento de áudio, permissões e compatibilidade são pontos centrais.

O exemplo abaixo é de síntese de fala, em que uma frase é transformada em áudio pelo mecanismo do navegador. Em aplicações reais, é comum controlar fila de falas e cancelar falas em andamento com speechSynthesis.cancel(). Também pode ser útil selecionar vozes disponíveis via speechSynthesis.getVoices(), pois nem sempre há a mesma disponibilidade de vozes por sistema. O trecho abaixo mantém o comportamento simples e direto.

// Texto para fala com Web Speech API (síntese)
function falarTexto() {
  const textoParaFalar = "Olá, esta é uma demonstração de síntese de fala.";
  const fala = new SpeechSynthesisUtterance(textoParaFalar);

  fala.lang = "pt-BR";
  fala.rate = 1.0;
  fala.pitch = 1.0;
  fala.volume = 1.0;

  window.speechSynthesis.speak(fala);
}

falarTexto();

Speech Recognition (voz para texto) com compatibilidade limitada

O reconhecimento de fala converte áudio do microfone em texto, possibilitando ditado e comandos por voz. Em vários ambientes, a API é exposta como webkitSpeechRecognition, o que indica suporte não padronizado em todos os navegadores. Normalmente é necessário lidar com eventos como resultado, erro e fim da captura. Também é importante considerar que o reconhecimento pode depender de serviços do navegador e variar em qualidade conforme ruído e idioma.

O exemplo a seguir inicia uma sessão simples e registra a transcrição do primeiro resultado. Em um cenário mais completo, seria comum habilitar resultados contínuos, tratar resultados parciais e controlar reinícios quando a captura termina. Também é relevante tratar o caso em que o suporte não existe e oferecer alternativas. O código foca no mínimo para demonstrar o fluxo de eventos.

// Voz para texto (suporte comum em Chrome/Edge via prefixo)
function iniciarReconhecimentoDeVoz() {
  const Reconhecimento = window.SpeechRecognition || window.webkitSpeechRecognition;

  if (!Reconhecimento) {
    console.error("Reconhecimento de fala indisponível neste navegador.");
    return;
  }

  const reconhecimento = new Reconhecimento();
  reconhecimento.lang = "pt-BR";
  reconhecimento.interimResults = false;
  reconhecimento.continuous = false;

  reconhecimento.onresult = (e) => {
    const texto = e.results[0][0].transcript;
    console.log("Texto reconhecido:", texto);
  };

  reconhecimento.onerror = (e) => {
    console.error("Erro no reconhecimento de voz:", e.error);
  };

  reconhecimento.onend = () => {
    console.log("Reconhecimento finalizado.");
  };

  reconhecimento.start();
}

iniciarReconhecimentoDeVoz();

Fetch API para requisições HTTP modernas

A Fetch API é a interface moderna para buscar recursos pela rede usando HTTP. Ela trabalha com Promises, que representam operações assíncronas, e retorna um objeto Response com status, cabeçalhos e corpo. Em JSON, é comum chamar response.json() para converter o corpo para objeto JavaScript. Para qualidade de código, é importante verificar response.ok e tratar erros de rede e erros HTTP de forma separada.

O exemplo abaixo busca um JSON, valida se a resposta foi bem-sucedida e então imprime os dados. Em produção, também entram controle de timeout (por exemplo via AbortController), envio de cabeçalhos e autenticação. Outro cuidado relevante é o CORS (Cross-Origin Resource Sharing), que controla se um servidor permite requisições vindas de outra origem. O trecho abaixo cobre o padrão mais comum e seguro para iniciantes.

// Requisição HTTP com Fetch API e validação de status
async function carregarFilmes() {
  try {
    const resposta = await fetch("http://example.com/movies.json", {
      method: "GET",
      headers: { "Accept": "application/json" }
    });

    if (!resposta.ok) {
      throw new Error("Resposta HTTP inválida: " + resposta.status);
    }

    const dados = await resposta.json();
    console.log("Dados recebidos:", dados);
  } catch (erro) {
    console.error("Erro na requisição:", erro);
  }
}

carregarFilmes();

Web Audio API para geração e processamento de áudio

A Web Audio API fornece um sistema avançado para criar e manipular áudio no navegador. Ela funciona com um grafo de nós, em que fontes (como osciladores e arquivos) passam por efeitos e chegam até a saída de áudio. O ponto de entrada é um AudioContext, que controla tempo, criação de nós e roteamento. Por políticas de reprodução automática, muitos navegadores exigem que o áudio comece após uma interação do usuário.

O exemplo a seguir cria um oscilador com frequência de 440 Hz, o “Lá” padrão, e toca por um segundo. Em aplicações mais elaboradas, entram nós como GainNode (volume), BiquadFilterNode (filtros) e analisadores para visualização. Também é comum gerenciar o ciclo de vida do contexto e liberar recursos. O exemplo mantém a estrutura essencial para demonstrar criação, conexão e execução.

// Geração simples de tom com Web Audio API
async function tocarTom() {
  const AudioCtx = window.AudioContext || window.webkitAudioContext;

  if (!AudioCtx) {
    console.error("Web Audio API não suportada neste navegador.");
    return;
  }

  const contexto = new AudioCtx();

  const oscilador = contexto.createOscillator();
  oscilador.type = "sine";
  oscilador.frequency.setValueAtTime(440, contexto.currentTime);

  const ganho = contexto.createGain();
  ganho.gain.setValueAtTime(0.1, contexto.currentTime); // volume baixo

  oscilador.connect(ganho);
  ganho.connect(contexto.destination);

  oscilador.start();
  oscilador.stop(contexto.currentTime + 1);

  oscilador.onended = async () => {
    await contexto.close();
  };
}

tocarTom();

File API para acesso a arquivos selecionados pelo usuário

A File API permite que a aplicação leia metadados e conteúdo de arquivos fornecidos pelo próprio usuário, geralmente via um elemento input do tipo file. O navegador não permite acesso arbitrário ao disco; o usuário precisa escolher o arquivo. Uma vez selecionado, o arquivo aparece como um objeto File, que é um tipo de Blob (dados binários). A leitura do conteúdo pode ser feita por FileReader ou por métodos modernos como file.text().

O exemplo abaixo mostra a captura do arquivo selecionado e a leitura como texto quando aplicável. Em uploads reais, o arquivo é enviado com fetch usando FormData para multipart/form-data. Também é importante validar tamanho, tipo MIME e lidar com múltiplos arquivos. O trecho abaixo mantém o foco no acesso inicial e na inspeção do arquivo.

O bloco a seguir apresenta um exemplo completo em HTML e JavaScript para selecionar um arquivo e ler seu conteúdo.

<input type="file" id="entradaArquivo" accept="image/*,text/plain">
<button id="btnLer">Ler arquivo</button>

<script>
  async function lerArquivoSelecionado() {
    const input = document.getElementById("entradaArquivo");
    const arquivo = input.files && input.files[0];

    if (!arquivo) {
      console.log("Nenhum arquivo selecionado.");
      return;
    }

    console.log("Arquivo:", {
      nome: arquivo.name,
      tipo: arquivo.type,
      tamanho: arquivo.size
    });

    if (arquivo.type.startsWith("text/")) {
      const conteudo = await arquivo.text();
      console.log("Conteúdo do texto:", conteudo);
    } else {
      console.log("Arquivo não textual selecionado.");
    }
  }

  document.getElementById("btnLer").addEventListener("click", lerArquivoSelecionado);
</script>

IndexedDB para armazenamento estruturado e volumoso no navegador

IndexedDB é uma API de baixo nível para armazenar grandes volumes de dados estruturados no lado do cliente. Ela é baseada em bancos de dados com object stores (semelhantes a tabelas simples) e indexes (índices) para consultas rápidas. Diferente de armazenamento por chave/valor simples, o IndexedDB suporta buscas eficientes e guarda objetos complexos. Por ser assíncrona e orientada a eventos, a abertura do banco envolve callbacks como onupgradeneeded e onsuccess.

Um ponto crítico é o controle de versão: ao mudar a estrutura do banco, incrementa-se a versão e cria-se ou ajusta-se stores e índices no onupgradeneeded. Também é essencial entender transações, porque leituras e escritas acontecem dentro de uma transaction. O exemplo abaixo cria um banco simples com uma store de posts e demonstra inserção e leitura. Ele serve como base para cache offline, rascunhos e dados de sessão persistentes.

O bloco a seguir apresenta a abertura do banco, criação de store e operações básicas.

// IndexedDB: criação de banco, store e operações básicas
const nomeBanco = "PostsDB";
const versaoBanco = 1;

function abrirBanco() {
  return new Promise((resolve, reject) => {
    const requisicao = indexedDB.open(nomeBanco, versaoBanco);

    requisicao.onerror = () => reject(new Error("Erro ao abrir o banco IndexedDB."));

    requisicao.onupgradeneeded = (evento) => {
      const db = evento.target.result;

      if (!db.objectStoreNames.contains("posts")) {
        const store = db.createObjectStore("posts", { keyPath: "id" });
        store.createIndex("porData", "criadoEm", { unique: false });
      }
    };

    requisicao.onsuccess = () => resolve(requisicao.result);
  });
}

async function salvarPost(post) {
  const db = await abrirBanco();
  return new Promise((resolve, reject) => {
    const tx = db.transaction("posts", "readwrite");
    const store = tx.objectStore("posts");

    const req = store.put(post);

    req.onsuccess = () => resolve(true);
    req.onerror = () => reject(new Error("Falha ao salvar post."));

    tx.oncomplete = () => db.close();
  });
}

async function listarPosts() {
  const db = await abrirBanco();
  return new Promise((resolve, reject) => {
    const tx = db.transaction("posts", "readonly");
    const store = tx.objectStore("posts");

    const req = store.getAll();

    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(new Error("Falha ao listar posts."));

    tx.oncomplete = () => db.close();
  });
}

// Demonstração
(async () => {
  await salvarPost({ id: "1", texto: "Primeiro post", criadoEm: Date.now() });
  const posts = await listarPosts();
  console.log("Posts:", posts);
})();

WebSockets para comunicação bidirecional em tempo real

A WebSocket API permite abrir uma conexão persistente e bidirecional entre navegador e servidor. Diferente de requisições HTTP tradicionais, que são pontuais, o WebSocket mantém um canal aberto para envio e recebimento imediato de mensagens. Isso é útil para chat, atualizações em tempo real, telemetria e dashboards ao vivo. O endereço começa com wss:// quando a conexão é criptografada.

O exemplo abaixo cria um socket, envia uma mensagem ao abrir e registra mensagens recebidas. Em cenários reais, entram estratégias de reconexão, autenticação e protocolos de mensagens (por exemplo JSON com tipo e payload). Também é comum tratar eventos de erro e encerrar a conexão adequadamente. O trecho demonstra o ciclo básico de eventos: open, message e close.

// Comunicação em tempo real com WebSocket
function iniciarWebSocket() {
  const socket = new WebSocket("wss://example.com/socket");

  socket.addEventListener("open", () => {
    console.log("Conexão aberta.");
    socket.send("Olá, servidor!");
  });

  socket.addEventListener("message", (event) => {
    console.log("Mensagem recebida:", event.data);
  });

  socket.addEventListener("error", () => {
    console.error("Erro no WebSocket.");
  });

  socket.addEventListener("close", () => {
    console.log("Conexão encerrada.");
  });

  return socket;
}

iniciarWebSocket();

Notifications API para notificações do sistema

A Notifications API permite exibir notificações do sistema operacional a partir do navegador, desde que haja permissão. Ela é frequentemente combinada com Push e Service Workers, mas também pode ser usada localmente enquanto a página está aberta. Como envolve interrupção, a permissão pode ser “granted”, “denied” ou “default”. Em alguns navegadores, o conteúdo e o comportamento podem variar para manter consistência e segurança.

O exemplo a seguir solicita permissão e cria uma notificação simples. Em usos mais completos, pode-se usar opções como body, icon e ações, além de tratar cliques na notificação. Também é importante evitar excessos para não degradar a experiência e causar bloqueios de permissão. O trecho demonstra o fluxo mínimo com tratamento básico do resultado.

// Notificação simples com Notifications API
async function notificar() {
  if (!("Notification" in window)) {
    console.error("Notifications API não suportada neste navegador.");
    return;
  }

  const permissao = await Notification.requestPermission();

  if (permissao === "granted") {
    new Notification("Olá, mundo!", { body: "Notificação exibida pelo navegador." });
  } else {
    console.log("Permissão não concedida:", permissao);
  }
}

notificar();

Intersection Observer para observar elementos entrando na tela

A Intersection Observer API observa mudanças de interseção entre um elemento alvo e o viewport, sem precisar de cálculos constantes de scroll. Isso é útil para carregamento preguiçoso (lazy loading), animações ao aparecer e métricas de visibilidade. Ela funciona de forma assíncrona e tende a ser mais eficiente do que escutar scroll e recalcular posições. O observador recebe entradas (entries) com informações como isIntersecting e proporção visível.

O exemplo abaixo observa um elemento e registra quando ele entra no viewport. Em casos reais, configura-se threshold e rootMargin para ajustar a sensibilidade e antecipar carregamento. Também é comum chamar unobserve após a primeira interseção, para não repetir processamento. O código mostra a estrutura essencial e o ponto de observação.

// Observação de visibilidade com IntersectionObserver
function observarElemento(idElemento) {
  const alvo = document.getElementById(idElemento);

  if (!alvo) {
    console.error("Elemento não encontrado:", idElemento);
    return;
  }

  const observer = new IntersectionObserver((entradas) => {
    entradas.forEach((entrada) => {
      if (entrada.isIntersecting) {
        console.log("Elemento visível no viewport:", idElemento);
      }
    });
  }, { threshold: 0.1 });

  observer.observe(alvo);
}

observarElemento("yourElementId");

Web Workers para executar tarefas em segundo plano

Web Workers permitem rodar JavaScript em uma thread separada da thread principal da página. Isso ajuda a evitar travamentos na interface quando há cálculos pesados, como processamento de dados, compressão ou parsing grande. A comunicação acontece por mensagens com postMessage e eventos de message. O Worker não acessa diretamente o DOM, o que reforça separação e previsibilidade.

O exemplo abaixo mostra a criação de um worker e a troca de mensagens. Em cenários reais, pode-se enviar objetos grandes usando cópia estruturada e, quando possível, usar Transferable para mover buffers sem copiar. Também é importante lidar com erros do worker e encerrá-lo com terminate() quando não for mais necessário. O trecho inclui o script principal e um exemplo de arquivo worker.

O bloco a seguir apresenta o código do script principal.

// Script principal: cria worker e envia mensagem
function iniciarWorker() {
  const worker = new Worker("worker.js");

  worker.onmessage = (e) => {
    console.log("Mensagem do worker:", e.data);
  };

  worker.onerror = () => {
    console.error("Erro no worker.");
  };

  worker.postMessage({ texto: "Olá do script principal!", numero: 10 });

  return worker;
}

iniciarWorker();

O bloco a seguir apresenta um exemplo de conteúdo para o arquivo worker.js.

// worker.js: processa dados em segundo plano
self.onmessage = (e) => {
  const { texto, numero } = e.data;

  // Processamento simples para demonstração
  const resultado = {
    recebido: texto,
    dobro: numero * 2
  };

  self.postMessage(resultado);
};

Mutation Observer para detectar alterações no DOM

A MutationObserver API monitora mudanças na árvore DOM, como adição/remoção de nós e alterações de atributos. Ela substitui eventos antigos de mutação, oferecendo melhor desempenho e um modelo de observação mais controlado. Isso é útil para componentes que precisam reagir quando um trecho da página muda, como listas dinâmicas ou integração com conteúdo inserido por terceiros. O observador recebe uma lista de mutações, cada uma descrevendo o que mudou.

O exemplo abaixo observa atributos, filhos e subárvore de um elemento. Em produção, é comum filtrar tipos de mutação e desligar a observação quando não for necessária, evitando processamento constante. Também é importante evitar loops, onde o código reage a uma mutação gerando outra mutação repetidamente. O trecho mostra a configuração essencial e o início da observação.

// Detecção de mudanças no DOM com MutationObserver
function observarMudancasDOM(idElemento) {
  const alvo = document.getElementById(idElemento);

  if (!alvo) {
    console.error("Elemento não encontrado:", idElemento);
    return;
  }

  const observer = new MutationObserver((mutacoes) => {
    mutacoes.forEach((mutacao) => {
      console.log("Mudança detectada:", {
        tipo: mutacao.type,
        atributo: mutacao.attributeName
      });
    });
  });

  const config = { attributes: true, childList: true, subtree: true };
  observer.observe(alvo, config);

  return observer;
}

observarMudancasDOM("yourElementId");

Pointer Lock API para capturar movimento bruto do mouse

A Pointer Lock API permite “travar” o ponteiro do mouse em um elemento e receber movimento relativo, em vez da posição absoluta do cursor. Isso é muito usado em jogos 3D e experiências imersivas, onde o movimento contínuo do mouse controla câmera e rotação. Por segurança e previsibilidade, a ativação geralmente precisa ocorrer após uma interação do usuário. O estado pode ser acompanhado por eventos como pointerlockchange.

O exemplo abaixo solicita o pointer lock em um elemento. Em um cenário completo, é comum também ouvir movimento do mouse com mousemove e usar as propriedades movementX e movementY. Também é importante oferecer uma forma clara de sair do lock, geralmente via tecla Esc, gerenciada pelo próprio navegador. O trecho apresenta a chamada central e um monitoramento simples de mudança de estado.

// Ativação de Pointer Lock em um elemento
function ativarPointerLock(idElemento) {
  const elemento = document.getElementById(idElemento);

  if (!elemento) {
    console.error("Elemento não encontrado:", idElemento);
    return;
  }

  document.addEventListener("pointerlockchange", () => {
    const travado = document.pointerLockElement === elemento;
    console.log("Pointer lock ativo:", travado);
  });

  elemento.requestPointerLock();
}

ativarPointerLock("yourElementId");

Web Storage API: sessionStorage e localStorage

A Web Storage API oferece armazenamento simples de pares chave/valor em formato de string. O sessionStorage dura enquanto a aba estiver aberta, e é isolado por aba. O localStorage persiste mesmo após fechar e abrir o navegador, dentro do mesmo domínio. Por serem strings, objetos precisam ser serializados, normalmente com JSON.stringify, e recuperados com JSON.parse.

O exemplo abaixo mostra gravação, leitura e remoção em ambos. O Web Storage é útil para preferências simples e pequenos estados, mas não é ideal para grandes volumes ou buscas complexas, onde o IndexedDB é mais apropriado. Também é importante evitar guardar dados sensíveis, pois ficam acessíveis por scripts do mesmo domínio. O trecho demonstra os dois tipos e um padrão seguro para objetos com JSON.

// sessionStorage: dura enquanto a aba existir
sessionStorage.setItem("chave", "valor");
const valorSession = sessionStorage.getItem("chave");
console.log("sessionStorage:", valorSession);
sessionStorage.removeItem("chave");

// localStorage: persiste no navegador
localStorage.setItem("chave", "valor");
const valorLocal = localStorage.getItem("chave");
console.log("localStorage:", valorLocal);
localStorage.removeItem("chave");

// Salvando objeto com JSON
const preferencias = { tema: "escuro", tamanhoFonte: 16 };
localStorage.setItem("preferencias", JSON.stringify(preferencias));

const preferenciasLidas = JSON.parse(localStorage.getItem("preferencias") || "{}");
console.log("Preferências:", preferenciasLidas);

Battery Status API para obter informações de bateria

A Battery Status API (ou Battery API) fornece informações como nível de carga e se o dispositivo está carregando. Ela pode ajudar a adaptar comportamentos, como reduzir tarefas pesadas quando a bateria está baixa. A API retorna um objeto de bateria com propriedades e eventos, permitindo reagir a mudanças. Por questões de privacidade e padronização, a disponibilidade pode ser limitada em alguns navegadores.

O exemplo abaixo lê nível e estado de carregamento. Em usos mais avançados, pode-se assinar eventos como levelchange e chargingchange. Também é relevante tratar o caso de não suporte, evitando falhas silenciosas. O trecho demonstra leitura inicial com logs simples.

// Informações de bateria com Battery API (quando disponível)
async function lerBateria() {
  if (!navigator.getBattery) {
    console.error("Battery API não suportada neste navegador.");
    return;
  }

  const bateria = await navigator.getBattery();
  console.log("Nível da bateria:", Math.round(bateria.level * 100) + "%");
  console.log("Carregando:", bateria.charging ? "Sim" : "Não");
}

lerBateria();

Orientation and Motion API para sensores de orientação e movimento

A Orientation and Motion API usa sensores do dispositivo, como acelerômetro e giroscópio, para expor orientação e movimento. O evento deviceorientation fornece ângulos que representam rotação do aparelho em diferentes eixos. O evento devicemotion fornece aceleração e, em alguns casos, rotação. Por privacidade e segurança, alguns ambientes exigem permissões explícitas e interação prévia para liberar sensores.

O exemplo abaixo registra eventos e imprime valores básicos. Em aplicações reais, é comum filtrar ruído com suavização, limitar taxa de atualização e lidar com valores nulos dependendo do hardware. Também é útil normalizar comportamento entre dispositivos, pois a calibração pode variar. O trecho demonstra como assinar os dois eventos mais comuns.

// Eventos de orientação e movimento
window.addEventListener("deviceorientation", (event) => {
  console.log("Orientação:", {
    alpha: event.alpha,
    beta: event.beta,
    gamma: event.gamma
  });
});

window.addEventListener("devicemotion", (event) => {
  const acc = event.acceleration;
  if (!acc) {
    console.log("Aceleração indisponível.");
    return;
  }

  console.log("Movimento:", {
    x: acc.x,
    y: acc.y,
    z: acc.z
  });
});

Gamepad API para controle de videogame no navegador

A Gamepad API permite detectar e ler entradas de controles conectados ao dispositivo, como gamepads USB ou Bluetooth. Ela expõe botões e eixos (analógicos), permitindo mapear ações como pular, correr e mover câmera. O navegador dispara eventos quando um controle conecta ou desconecta. Para leitura contínua dos estados, costuma-se usar um loop com requestAnimationFrame.

O exemplo abaixo registra conexão e desconexão e mostra como consultar o estado do controle. Em usos reais, também é comum lidar com múltiplos gamepads e com diferenças de mapeamento entre modelos. Um cuidado importante é evitar assumir que o layout de botões é sempre igual, pois pode variar. O trecho demonstra eventos e uma leitura simples periódica.

// Detecção e leitura simples de Gamepad
window.addEventListener("gamepadconnected", (event) => {
  console.log("Gamepad conectado:", event.gamepad.id);
});

window.addEventListener("gamepaddisconnected", (event) => {
  console.log("Gamepad desconectado:", event.gamepad.id);
});

function lerEstadoGamepad() {
  const gamepads = navigator.getGamepads ? navigator.getGamepads() : [];
  const gp = gamepads[0];

  if (gp) {
    console.log("Eixo 0:", gp.axes[0], "Botão 0 pressionado:", gp.buttons[0].pressed);
  }

  requestAnimationFrame(lerEstadoGamepad);
}

lerEstadoGamepad();

Clipboard API para copiar texto com segurança

A Clipboard API permite copiar e, em alguns casos, ler dados da área de transferência. O uso mais comum é copiar texto, como códigos, links e resultados de ferramentas. Em geral, é exigido contexto seguro (HTTPS) e, com frequência, uma ação do usuário para permitir a operação. O método navigator.clipboard.writeText retorna uma Promise e permite tratamento de sucesso e falha.

O exemplo abaixo copia uma string e registra o resultado. Em aplicações reais, é comum fornecer retorno visual e tratar erros de permissão, especialmente em navegadores que restringem chamadas automáticas. Também pode haver diferenças de comportamento em ambientes móveis. O trecho mantém o foco no fluxo básico com tratamento de erro.

// Copiar texto para a área de transferência
async function copiarTexto() {
  if (!navigator.clipboard || !navigator.clipboard.writeText) {
    console.error("Clipboard API não suportada neste navegador.");
    return;
  }

  try {
    await navigator.clipboard.writeText("Texto copiado com sucesso!");
    console.log("Texto copiado.");
  } catch (erro) {
    console.error("Falha ao copiar texto:", erro);
  }
}

copiarTexto();

Geolocation API para obter localização do dispositivo

A Geolocation API retorna coordenadas aproximadas de latitude e longitude, dependendo de GPS, Wi‑Fi e rede. Por ser um dado sensível, exige permissão e normalmente só funciona em contexto seguro (HTTPS). O método getCurrentPosition traz uma leitura pontual, e watchPosition acompanha mudanças ao longo do tempo. É importante lidar com erros, como permissão negada, timeout e indisponibilidade.

O exemplo abaixo busca a posição atual e registra coordenadas. Em aplicações reais, também se usa precisão (accuracy) e timestamp, além de configurar opções como enableHighAccuracy e timeout. Outro cuidado é que a localização pode ser aproximada em desktops, e pode variar conforme permissões do sistema. O trecho inclui callbacks de sucesso e erro para robustez.

// Localização pontual com Geolocation API
function obterLocalizacao() {
  if (!navigator.geolocation) {
    console.error("Geolocation API não suportada neste navegador.");
    return;
  }

  navigator.geolocation.getCurrentPosition(
    (posicao) => {
      console.log("Latitude:", posicao.coords.latitude);
      console.log("Longitude:", posicao.coords.longitude);
      console.log("Precisão (m):", posicao.coords.accuracy);
    },
    (erro) => {
      console.error("Erro de geolocalização:", erro.code, erro.message);
    },
    { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
  );
}

obterLocalizacao();

MediaDevices API para acessar câmera e microfone

A MediaDevices API, através de getUserMedia, permite capturar áudio e vídeo do microfone e da câmera. Ela é usada em chamadas, gravações, leitura de QR Code e captura de imagens. O retorno é um MediaStream, que pode ser ligado a um elemento de vídeo ou áudio. Por envolver hardware e privacidade, requer permissão e normalmente HTTPS.

O exemplo abaixo inicia um stream de vídeo e o conecta a um elemento video. Em aplicações reais, costuma-se enumerar dispositivos com enumerateDevices, escolher câmera frontal/traseira no celular e parar faixas com track.stop() ao finalizar. Também é importante tratar erros como NotAllowedError e NotFoundError. O trecho inclui o HTML mínimo necessário e o JavaScript correspondente.

O bloco a seguir apresenta um exemplo completo de captura de câmera.

<video id="preview" autoplay playsinline muted></video>

<script>
  async function iniciarCamera() {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      console.error("MediaDevices API não suportada neste navegador.");
      return;
    }

    try {
      const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
      const video = document.getElementById("preview");
      video.srcObject = stream;

      console.log("Câmera iniciada.");
    } catch (erro) {
      console.error("Erro ao acessar câmera:", erro.name, erro.message);
    }
  }

  iniciarCamera();
</script>

MediaRecorder API para gravar áudio (e vídeo, quando suportado)

A MediaRecorder API grava um MediaStream e produz blocos (chunks) de mídia, geralmente em formatos como webm/ogg dependendo do navegador. Ela é comum em mensagens de voz e gravações rápidas no browser. O ciclo típico é criar o MediaRecorder, iniciar, coletar dados via ondataavailable e finalizar com stop. Depois, os chunks são combinados em um Blob para reprodução ou upload.

O exemplo abaixo grava áudio por três segundos e gera um Blob ao final. Em produção, é comum exibir tempo de gravação, permitir pausa com pause() e resume(), e verificar suporte com MediaRecorder.isTypeSupported. Também é importante parar as tracks do microfone após terminar para liberar o hardware. O trecho demonstra o fluxo completo de início, coleta e finalização.

// Gravação simples de áudio com MediaRecorder
async function gravarAudioPor3s() {
  if (!navigator.mediaDevices || !window.MediaRecorder) {
    console.error("MediaRecorder/MediaDevices indisponíveis neste navegador.");
    return;
  }

  let stream;

  try {
    stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    const gravador = new MediaRecorder(stream);

    const partes = [];

    gravador.ondataavailable = (e) => {
      if (e.data && e.data.size > 0) partes.push(e.data);
    };

    gravador.onstop = () => {
      const blob = new Blob(partes, { type: gravador.mimeType || "audio/webm" });
      console.log("Áudio gravado (Blob):", blob);

      // Libera microfone
      stream.getTracks().forEach((t) => t.stop());
    };

    gravador.start();
    console.log("Gravação iniciada.");

    setTimeout(() => {
      gravador.stop();
      console.log("Gravação finalizada.");
    }, 3000);
  } catch (erro) {
    console.error("Erro ao gravar áudio:", erro.name, erro.message);
    if (stream) stream.getTracks().forEach((t) => t.stop());
  }
}

gravarAudioPor3s();

Fullscreen API para modo tela cheia

A Fullscreen API coloca um elemento, ou a página inteira, em modo tela cheia. É comum em players de vídeo, apresentações e painéis de monitoramento. A entrada e saída do modo tela cheia geralmente exigem gesto do usuário por segurança. O estado pode ser verificado com document.fullscreenElement e eventos como fullscreenchange.

O exemplo abaixo solicita tela cheia para o documento. Em cenários mais controlados, solicita-se para um elemento específico, como um container de vídeo. Também é comum tratar falhas com try/catch e oferecer saída chamando document.exitFullscreen(). O trecho demonstra entrada e observação de mudança.

// Tela cheia com Fullscreen API
async function entrarEmTelaCheia() {
  try {
    await document.documentElement.requestFullscreen();
    console.log("Tela cheia ativada.");
  } catch (erro) {
    console.error("Falha ao ativar tela cheia:", erro);
  }
}

document.addEventListener("fullscreenchange", () => {
  console.log("Estado fullscreen:", !!document.fullscreenElement);
});

entrarEmTelaCheia();

Drag and Drop API para arrastar e soltar arquivos

A Drag and Drop API permite arrastar itens, incluindo arquivos do sistema, para dentro da página. Em uploads, é comum prevenir o comportamento padrão do navegador e ler dataTransfer.files. A API trabalha com eventos como dragover e drop. Como o input é fornecido pelo usuário, é um fluxo natural para seleção de arquivos.

O exemplo abaixo captura arquivos soltos no documento. Em implementações reais, costuma-se limitar a área de drop a um elemento específico e validar tipos e tamanhos. Também é comum adicionar feedback visual durante dragover e remover ao dragleave. O trecho mostra o essencial para interceptar e obter a lista de arquivos.

// Drag and Drop básico para capturar arquivos
document.addEventListener("dragover", (e) => {
  e.preventDefault();
});

document.addEventListener("drop", (e) => {
  e.preventDefault();
  const arquivos = e.dataTransfer.files;
  console.log("Arquivos soltos:", arquivos);
});

Network Information API para estimar tipo de conexão

A Network Information API expõe informações estimadas sobre a conexão, como effectiveType, que pode indicar “slow-2g”, “2g”, “3g” ou “4g”. Isso pode orientar decisões como reduzir qualidade de mídia e adiar downloads pesados. Por ser um dado sensível e variável, o suporte pode ser parcial e os valores são aproximações. Em geral, ela é um sinal para adaptação, não uma garantia de velocidade real.

O exemplo abaixo registra o effectiveType quando disponível. Em um caso completo, também se observa mudanças com evento “change” na conexão. É importante sempre ter fallback, pois a API pode não existir. O trecho demonstra leitura defensiva e log do valor.

// Leitura simples de tipo de conexão (quando suportado)
function lerInfoRede() {
  const conexao = navigator.connection || navigator.mozConnection || navigator.webkitConnection;

  if (!conexao) {
    console.error("Network Information API não suportada neste navegador.");
    return;
  }

  console.log("Tipo efetivo de conexão:", conexao.effectiveType);
}

lerInfoRede();

Page Visibility API para detectar quando a página está oculta

A Page Visibility API informa se a página está visível ou em segundo plano, o que ajuda a reduzir consumo de CPU e bateria. Quando o documento fica oculto, pode-se pausar animações, timers e atualizações desnecessárias. O estado é exposto por document.hidden e pelo evento visibilitychange. É uma API simples, mas muito útil para otimização.

O exemplo abaixo registra mudanças de visibilidade. Em aplicações reais, essa informação pode ser combinada com estado de reprodução de mídia, sincronização e reconexão de sockets. Também é útil para adiar processamento pesado até a aba voltar ao foco. O trecho demonstra o padrão de assinatura do evento.

// Monitoramento de visibilidade da página
document.addEventListener("visibilitychange", () => {
  console.log(document.hidden ? "Página oculta" : "Página ativa");
});

File System Access API para salvar arquivo localmente (suporte limitado)

A File System Access API permite abrir e salvar arquivos diretamente no sistema de arquivos, com um seletor controlado pelo navegador. Ela é muito útil em editores online e exportações, porque o conteúdo pode ser gravado sem precisar gerar download tradicional. Por segurança, sempre depende de interação do usuário e do prompt do navegador. O suporte costuma ser mais presente em navegadores baseados em Chromium.

O exemplo abaixo abre o seletor de salvamento, cria um escritor (writable), grava texto e fecha o arquivo. Em usos mais completos, também é comum salvar binários, manter o handle para salvamentos subsequentes e tratar cancelamento do seletor. Também é importante capturar exceções, pois o usuário pode cancelar a operação. O trecho demonstra o ciclo completo de escrita.

// Salvamento local com File System Access API (quando suportado)
async function salvarArquivoLocal() {
  if (!window.showSaveFilePicker) {
    console.error("File System Access API não suportada neste navegador.");
    return;
  }

  try {
    const handle = await window.showSaveFilePicker({
      suggestedName: "arquivo.txt",
      types: [
        {
          description: "Texto",
          accept: { "text/plain": [".txt"] }
        }
      ]
    });

    const writable = await handle.createWritable();
    await writable.write("Conteúdo do arquivo");
    await writable.close();

    console.log("Arquivo salvo com sucesso.");
  } catch (erro) {
    console.error("Falha ao salvar (cancelamento ou erro):", erro);
  }
}

salvarArquivoLocal();

Web Share API para compartilhar conteúdo no celular

A Web Share API permite acionar o compartilhamento nativo do sistema, comum em navegadores móveis. Ela envia dados como título, texto e URL para os apps disponíveis no dispositivo. Por design, normalmente funciona melhor em mobile e exige contexto seguro. O método navigator.share retorna uma Promise, permitindo detectar sucesso ou cancelamento.

O exemplo abaixo compartilha o título e a URL atual. Em aplicações reais, é comum validar suporte com navigator.canShare quando arquivos também podem ser compartilhados. Também é importante tratar o caso de cancelamento sem tratar como erro crítico. O trecho mostra um fluxo básico com fallback de log em caso de não suporte.

// Compartilhamento nativo com Web Share API
async function compartilharPagina() {
  if (!navigator.share) {
    console.error("Web Share API não suportada neste navegador.");
    return;
  }

  try {
    await navigator.share({
      title: "Meu site",
      url: location.href
    });
    console.log("Compartilhamento concluído.");
  } catch (erro) {
    console.error("Compartilhamento cancelado ou falhou:", erro);
  }
}

compartilharPagina();

Performance API para medir tempos e obter métricas

A Performance API oferece ferramentas para medir tempo com alta resolução e inspecionar métricas de carregamento. O método performance.now() retorna um tempo em milissegundos com precisão superior ao Date.now, ideal para medir duração de operações. Também existem entradas de performance (PerformanceEntry) para navegação e recursos, dependendo do nível de acesso permitido. Isso ajuda a entender gargalos e a comparar melhorias.

O exemplo abaixo mede o tempo de execução de um bloco de código. Em aplicações maiores, também é comum usar performance.mark e performance.measure para medições nomeadas. Outro cuidado é medir com consistência, repetindo e descartando aquecimentos quando aplicável. O trecho demonstra medição simples e legível.

// Medição simples com Performance API
function medirOperacao() {
  const inicio = performance.now();

  // Operação simulada
  let soma = 0;
  for (let i = 0; i < 1_000_000; i++) soma += i;

  const fim = performance.now();
  console.log("Tempo (ms):", (fim - inicio).toFixed(2), "Soma:", soma);
}

medirOperacao();

Panorama coerente das APIs e limites práticos

O conjunto apresentado cobre desde comunicação e armazenamento até recursos de hardware e experiência do sistema. Algumas APIs são amplamente suportadas e estáveis, como Fetch, Web Storage, Intersection Observer e WebSocket. Outras são mais sensíveis a permissões e políticas, como Geolocation, MediaDevices, Notifications e Push. E há APIs com suporte limitado, como Web NFC e File System Access.

No caso de RFID, a realidade prática costuma exigir integração por hardware dedicado e software nativo ou camadas intermediárias, enquanto o NFC é o caminho mais próximo quando se busca algo diretamente do navegador. Com essa visão completa, as APIs deixam de ser “recursos soltos” e passam a formar um mapa claro de capacidades, restrições e aplicações típicas. O resultado é uma base sólida para compreender o que a Web consegue acessar e como estruturar integrações de forma segura e previsível. A combinação adequada dessas interfaces sustenta aplicações modernas, ricas e alinhadas às regras do ambiente do navegador.