Popups JavaScript e window.open()
Aprenda a abrir, controlar e fechar janelas do navegador em JavaScript com window.open(), window.close(), eventos focus/blur e postMessage — incluindo restrições de segurança modernas e boas práticas.
Entre as capacidades do JavaScript, abrir e controlar janelas separadas do navegador permite criar fluxos de login, handshakes OAuth, pré-visualizações de impressão e superfícies ricas de notificação. Este capítulo cobre tudo que você precisa: abrir uma janela com window.open(), dimensioná-la e posicioná-la, trocar mensagens com ela, reagir a eventos de foco e descarregamento, e fechá-la corretamente — junto com as restrições de segurança modernas que definem como os navegadores tratam tudo isso.
Para os diálogos mais simples de uma linha (alert, prompt e confirm), consulte JavaScript alert, prompt e confirm. Esta página trata de janelas completas do navegador.
Entendendo Popups JavaScript
Um popup é uma janela separada de nível superior do navegador aberta pelo seu script. Ao contrário de um alert() modal, ele tem seu próprio documento, sua própria URL e permanece aberto até que o usuário (ou seu código) o feche. Popups são úteis para conteúdo que precisa existir fora da página atual — a tela de login de um provedor OAuth, um widget de pagamento ou um relatório para impressão. O único ponto de entrada para tudo isso é o método window.open().
Como window.open() funciona
window.open() aceita três argumentos e retorna uma referência para a nova janela (ou null se o navegador a bloqueou):
let win = window.open(url, name, features);| Argumento | Significado |
|---|---|
url | A página a carregar. Passe uma string vazia "" para abrir uma janela em branco que você preenche com script. |
name | Um nome de destino. Reutilizar o mesmo nome reutiliza a mesma janela em vez de abrir uma nova. Valores especiais como _blank sempre abrem uma nova janela. |
features | Uma string separada por vírgulas de opções como width=400,height=300,left=100,top=100. Omita para herdar os padrões. |
warning Os navegadores só permitem que
window.open()seja bem-sucedido quando executado diretamente dentro de um gesto do usuário, como um clique. Chamá-lo no carregamento da página ou em umsetTimeouté tratado como um popup não solicitado e é bloqueado —winretornanull. Sempre acione popups a partir de um manipulador de eventos real e verifique o valor de retorno.
Criando uma Janela Popup Básica
Para criar uma janela popup simples, chame window.open() a partir de um manipulador de clique. O método abre uma nova janela do navegador e retorna uma referência a ela, que você pode usar para manipular a janela posteriormente.
<p>Click the button to trigger the popup!</p>
<button onclick="openPopup()">Open Popup</button>
<script>
// Function to open a new popup with a message
function openPopup() {
let newWindow = window.open("", "Example", "width=400,height=400");
// Use innerHTML for safer dynamic content injection
newWindow.document.body.innerHTML = "<h1>Welcome to our popup!</h1>";
}
</script>warning Nota:
document.writepode sobrescrever o documento inteiro se chamado após o carregamento da página. A prática moderna prefereinnerHTMLou métodos de manipulação do DOM para injeção de conteúdo dinâmico mais segura.
Este trecho de código cria um botão na página web. Ao ser clicado, ele abre uma nova janela popup com dimensões 400x400 pixels e exibe uma mensagem de boas-vindas.
Controlando Conteúdo e Comportamento do Popup
Controlar o conteúdo e o comportamento dos popups é fundamental para garantir que eles contribuam positivamente para a experiência do usuário sem ser intrusivos.
<p>Click the button to trigger the popup!</p>
<button onclick="openInteractivePopup()">Learn More</button>
<script>
// Function to open a popup and control its content and behavior
function openInteractivePopup() {
// Open a new window with specific dimensions
let popup = window.open("", "InteractivePopupExample", "width=400,height=400");
// Use innerHTML to inject content safely
popup.document.body.innerHTML = `
<h1>Interactive Popup</h1>
<p>Click the button to change this message.</p>
<button onclick='document.body.innerHTML = "<h1>Content Updated!</h1><p>Thanks for interacting.</p>";'>Update Content</button>
`;
}
</script>Para comunicar-se com segurança entre a janela pai e o popup, use a propriedade window.opener para referenciar o pai, e postMessage() para troca de dados entre origens diferentes ou mais segura. Para um tratamento mais aprofundado deste tema, consulte Comunicação Entre Janelas.
<!-- In parent window -->
<script>
let popup = window.open("popup.html", "Popup", "width=400,height=400");
popup.postMessage("Hello from parent!", "*");
</script>
<!-- In popup window -->
<script>
window.addEventListener("message", (event) => {
console.log("Received:", event.data);
// Respond back if needed
window.opener.postMessage("Hello back!", event.origin);
});
</script>Aspectos Principais:
- Esta função não apenas abre um popup, mas também incorpora elementos interativos (como um botão dentro do popup).
- Ela demonstra o controle dinâmico do conteúdo do popup após a criação, o que é mais interativo e pode ser adaptado para reagir a entradas do usuário ou outros eventos.
Métodos e Eventos Avançados de Janela
Além dos popups básicos, JavaScript oferece uma variedade de métodos para interagir com janelas do navegador, aprimorando a funcionalidade e a interatividade do usuário.
Redimensionando e Movendo Elementos
JavaScript permite o redimensionamento e reposicionamento dinâmico de elementos da página, o que pode ser especialmente útil na criação de aplicações web responsivas e fáceis de usar. (Nota: window.resizeTo() e window.moveTo() existem para testes em ambientes legados ou restritos, mas os navegadores modernos os restringem fortemente por razões de segurança. Este exemplo simula o comportamento usando uma div estilizada. Para elementos de UI arrastáveis ou redimensionáveis, position: absolute é frequentemente preferível a relative para garantir cálculos de coordenadas previsíveis.)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Simulate Window Adjustments</title>
<style>
#simulatedWindow {
width: 300px;
height: 300px;
position: absolute;
background-color: #f3f3f3;
border: 2px solid #ccc;
margin: 20px;
padding: 10px;
transition: all 0.5s ease; /* Smooth transition for size and position changes */
}
</style>
</head>
<body>
<button onclick="adjustSimulatedWindow()">Adjust Window</button>
<div id="simulatedWindow">This is a simulated window. Click the button to adjust its size and position.</div>
<script>
function adjustSimulatedWindow() {
const elem = document.getElementById('simulatedWindow');
// Toggle size and position to demonstrate the effect
if (elem.style.width === '500px') {
elem.style.width = '300px';
elem.style.height = '300px';
elem.style.top = '0px';
elem.style.left = '0px';
} else {
elem.style.width = '500px';
elem.style.height = '500px';
elem.style.top = '100px';
elem.style.left = '100px';
}
}
</script>
</body>
</html>Aspectos Principais:
- Estrutura HTML: Inclui um botão e um elemento
divestilizado para parecer uma janela. Adivrepresenta a janela que "redimensionaremos" e "moveremos". - Estilização CSS: Define o tamanho e a posição iniciais da janela simulada, com transições suaves para efeito visual.
- Função JavaScript: Quando o botão é clicado, a função
adjustSimulatedWindowalterna o tamanho e a posição da janela simulada. A mudança de posição é gerenciada alterando as propriedades CSStopeleft, simulando o movimento de uma janela pela tela.
Manipulando Eventos de Janela
O tratamento de eventos é fundamental na criação de aplicações interativas. JavaScript fornece vários eventos relacionados a ações de janela, como onbeforeunload e onunload, que podem ser usados para executar código em momentos estratégicos.
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript Window Events Demo</title>
<style>
#message {
padding: 20px;
margin: 20px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<p>Watch how the message updates based on window events. Initially, it changes upon loading. If you attempt to exit or click the mock exit link below, a prompt will appear asking if you want to leave the page. Cancelling the action will update the message.</p>
<div id="message">Wait for it...</div>
<!-- Mock link for simulating page leave -->
<a href="#" onclick="simulatePageLeave(); return false;">Mock Page Leave</a>
<script>
window.onload = function() {
document.getElementById('message').innerHTML = '<strong>Window loaded successfully!</strong>';
};
// Function to simulate page leave
function simulatePageLeave() {
// Show dialog asking if the user really wants to leave
var confirmLeave = confirm('Are you sure you want to simulate leaving the page?');
if (confirmLeave) {
// If confirmed, update message as if leaving
document.getElementById('message').innerHTML = '<strong>Leaving the page...</strong>';
} else {
// If cancelled, update message accordingly
document.getElementById('message').innerHTML = '<strong>Decided to stay on the page!</strong>';
}
}
window.onbeforeunload = function() {
document.getElementById('message').innerHTML = '<strong>Preparing to leave the page...</strong>';
return 'Are you sure you want to leave?';
};
</script>
</body>
</html>Aspectos Principais:
- Link Simulado para Saída de Página: O link com
href="#"e um manipuladoronclickque chamasimulatePageLeave(); return false;simula o efeito de tentar sair da página. Oreturn false;impede a ação padrão do link, mantendo o usuário na página atual. - Diálogo de Confirmação: A função
simulatePageLeaveapresenta um diálogo de confirmação semelhante ao que ocorreria com uma tentativa real de descarregamento da página. Permite que os usuários decidam se desejam "sair" ou não. - Atualizações de Mensagem: Dependendo da escolha do usuário no diálogo de confirmação, a mensagem na
divé atualizada para refletir a escolha, imitando o comportamento esperado ao tentar realmente sair da página. - Nota sobre Comportamento do Navegador: Os navegadores modernos ignoram strings personalizadas retornadas por
onbeforeunloade exibem apenas um diálogo de confirmação padrão. O exemplo demonstra o acionamento do evento, mas o texto exato do aviso é controlado pelo navegador.
Alterar o innerHTML de um elemento torna as interações do usuário mais fluidas e menos perturbadoras. Esta abordagem funciona muito bem para sites interativos e ferramentas educacionais.
Fechando uma Janela Popup
É importante fornecer um mecanismo para que os usuários possam fechar facilmente os popups que você cria. Isso melhora a experiência do usuário, permitindo que eles controlem sua própria interação com sua aplicação.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Popup Example</title>
<script>
var myPopup = null; // Initialize the popup variable.
// Function to open a popup
function openPopup() {
// Check if the popup already exists and is not closed
if (myPopup === null || myPopup.closed) {
myPopup = window.open("", "PopupWindow", "width=400,height=400");
// Set the content of the popup using innerHTML
myPopup.document.body.innerHTML = `
<html>
<head><title>Popup Content</title></head>
<body>
<h1>Welcome!</h1>
<p>This is your popup window.</p>
<button onclick="window.close()">Close Window</button>
</body>
</html>
`;
// Ensure the popup gets focus
myPopup.focus();
} else {
// Bring the already opened popup to the front
myPopup.focus();
}
}
// Function to close the popup
function closePopup() {
if (myPopup && !myPopup.closed) {
myPopup.close();
myPopup = null; // Reset the popup variable after closing it.
}
}
</script>
</head>
<body>
<button onclick="openPopup()">Open Popup</button>
<button onclick="closePopup()">Close Popup</button>
</body>
</html>Aspectos Principais:
- Gerenciamento de Estado: A variável
myPopupé inicialmente definida comonulle verificada para saber se énullou foi fechada (myPopup.closed). Isso ajuda a decidir se deve criar um novo popup ou focar no existente. - Duplicação de Conteúdo: Ao garantir que o popup seja devidamente inicializado ou fechado, o problema de duplicação de conteúdo é evitado. Cada abertura do popup começa do zero.
- Gerenciamento de Foco: O uso de
myPopup.focus()garante que, se o popup já estiver aberto, ele venha para o primeiro plano quando "Abrir Popup" for clicado novamente.
Sempre teste o comportamento de popups e métodos de janela em diferentes navegadores e dispositivos para garantir compatibilidade e responsividade.
Focus e Blur em uma Janela
Os eventos focus e blur podem ser usados para detectar quando uma janela ou página ganha ou perde o foco. Isso pode ser útil para pausar atividades quando o usuário troca de aba ou janela.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Focus and Blur Events Demo</title>
<style>
body { transition: background-color 0.5s ease; } /* Smooth transition for background color */
</style>
<script>
// Function to handle focus event
function handleFocus() {
document.getElementById('status').innerHTML = 'Window is focused';
document.body.style.backgroundColor = '#DFF0D8'; // Light green background
}
// Function to handle blur event
function handleBlur() {
document.getElementById('status').innerHTML = 'Window is not focused';
document.body.style.backgroundColor = '#F2DEDE'; // Light red background
}
window.addEventListener('focus', handleFocus);
window.addEventListener('blur', handleBlur);
</script>
</head>
<body>
<h1>Focus and Blur Events on Window</h1>
<p>Status: <span id="status">Window is focused</span></p>
<p><strong>Instructions:</strong> To test this functionality, click inside this window to focus, then click away to another window or tab to trigger the blur effect. Notice the background color change and status update.</p>
</body>
</html>Aspectos Principais:
- Manipuladores de Evento:
handleFocus()ehandleBlur()atualizam o conteúdo da página e a cor de fundo com base no estado de foco da janela. - Feedback Visual: As mudanças na cor de fundo fornecem feedback visual imediato e claro sobre o estado de foco, aprimorando a experiência interativa.
Segurança e Bloqueadores de Popup
Como os popups foram historicamente abusados, os navegadores modernos impõem regras rígidas. Conhecê-las economiza horas de depuração do tipo "por que minha janela é null?".
- Requisito de gesto. Um popup só abre durante uma ação síncrona do usuário (clique, pressionamento de tecla, toque). Após um
awaitou umsetTimeout, o gesto é "consumido" e a chamada é bloqueada. window.openerenoopener. Quando você abre uma janela, a nova página pode ler e até navegar no abridor viawindow.opener. Para links a sites não confiáveis, isso representa um risco de phishing, portanto adicionerel="noopener"a âncoras ou passenoopenerna string de recursos:
// Anchor form — the new tab cannot touch this page
// <a href="https://example.com" target="_blank" rel="noopener noreferrer">Open</a>
// Scripted form — returns null because the link is severed
window.open("https://example.com", "_blank", "noopener");- Detectar um popup bloqueado. Sempre verifique o valor de retorno, pois uma chamada bloqueada retorna
null:
const win = window.open("/report", "report", "width=600,height=800");
if (!win || win.closed || typeof win.closed === "undefined") {
// Popup was blocked — fall back to navigating in the same tab
location.href = "/report";
}Boas Práticas para Usar Popups e Métodos de Janela
- Consentimento e Controle do Usuário: Sempre garanta que os popups não perturbem a experiência do usuário. Forneça controle suficiente para que os usuários fechem popups indesejados.
- Considerações de Segurança: Esteja ciente das implicações de segurança do conteúdo externo em popups. Use fontes confiáveis e conexões seguras para proteger os dados do usuário.
- Otimização de Desempenho: Use popups e métodos de janela com moderação, pois podem impactar o desempenho da sua aplicação web. Otimize o uso para equilibrar funcionalidade e eficiência de recursos.
Conclusão
Usar efetivamente os popups JavaScript e os métodos de janela pode melhorar significativamente a funcionalidade e a experiência do usuário das aplicações web. Seguindo os exemplos e as boas práticas fornecidos, os desenvolvedores podem implementar esses recursos de forma eficiente e responsável. Lembre-se de priorizar a experiência do usuário e a segurança em todas as implementações para manter a integridade e a eficácia das suas aplicações web.
Capítulos Relacionados
- JavaScript alert, prompt e confirm — os diálogos integrados mais simples.
- Comunicação Entre Janelas —
postMessage,window.openere a política de mesma origem em profundidade. - Tamanhos de Janela e Rolagem — lendo e controlando a geometria de uma janela.