W3docs

Popup JavaScript e window.open()

Apri, controlla e chiudi finestre del browser in JavaScript con window.open(), window.close(), eventi focus/blur, postMessage e best practice di sicurezza.

Tra le funzionalità di JavaScript, la possibilità di aprire e controllare finestre browser separate permette di creare flussi di login, handshake OAuth, anteprime di stampa e superfici di notifica avanzate. Questo capitolo copre tutto il necessario: aprire una finestra con window.open(), dimensionarla e posizionarla, scambiare messaggi con essa, reagire agli eventi focus e unload, e chiuderla correttamente — insieme alle moderne restrizioni di sicurezza che influenzano il comportamento dei browser in tutti questi contesti.

Per le finestre di dialogo più semplici su una sola riga (alert, prompt e confirm), consulta JavaScript alert, prompt e confirm. Questa pagina riguarda le finestre browser complete.

Comprendere i popup JavaScript

Un popup è una finestra browser separata di livello superiore aperta dal tuo script. A differenza di un alert() modale, ha il proprio documento, il proprio URL e rimane aperta finché l'utente (o il tuo codice) non la chiude. I popup sono utili per contenuti che devono esistere al di fuori della pagina corrente — la schermata di login di un provider OAuth, un widget di pagamento o un report stampabile. L'unico punto di accesso per tutto questo è il metodo window.open().

Come funziona window.open()

window.open() accetta tre argomenti e restituisce un riferimento alla nuova finestra (o null se il browser l'ha bloccata):

let win = window.open(url, name, features);
ArgomentoSignificato
urlLa pagina da caricare. Passa una stringa vuota "" per aprire una finestra vuota da riempire tramite script.
nameUn nome target. Riutilizzare lo stesso nome riutilizza la stessa finestra invece di aprirne una nuova. Valori speciali come _blank aprono sempre una nuova finestra.
featuresUna stringa di opzioni separate da virgola, come width=400,height=300,left=100,top=100. Omettila per ereditare i valori predefiniti.

warning I browser consentono a window.open() di avere successo solo quando viene eseguito direttamente all'interno di un'azione dell'utente come un clic. Chiamarlo al caricamento della pagina o in un setTimeout viene trattato come un popup non richiesto e viene bloccato — win restituisce null. Attiva sempre i popup da un handler di evento reale e verifica il valore restituito.

Creare una finestra popup di base

Per creare una semplice finestra popup, chiama window.open() da un handler di clic. Il metodo apre una nuova finestra browser e restituisce un riferimento ad essa, che puoi usare per manipolare ulteriormente la finestra.

<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.write può sovrascrivere l'intero documento se chiamato dopo il caricamento della pagina. La pratica moderna preferisce innerHTML o i metodi di manipolazione del DOM per un'iniezione di contenuto dinamico più sicura.

Questo frammento di codice crea un pulsante nella pagina web. Quando viene cliccato, apre una nuova finestra popup con dimensioni 400x400 pixel e visualizza un messaggio di benvenuto.

Controllare contenuto e comportamento dei popup

Controllare il contenuto e il comportamento dei popup è fondamentale per garantire che contribuiscano positivamente all'esperienza utente senza essere invadenti.

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

Per comunicare in modo sicuro tra la finestra padre e il popup, usa la proprietà window.opener per fare riferimento al padre e postMessage() per scambi di dati cross-origin o più sicuri. Per un approfondimento su questo argomento, consulta Comunicazione tra finestre.

<!-- 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>

Aspetti chiave:

  • Questa funzione non solo apre un popup, ma incorpora anche elementi interattivi (come un pulsante all'interno del popup).
  • Dimostra il controllo dinamico del contenuto del popup dopo la sua creazione, il che è più interattivo e può essere personalizzato per reagire agli input dell'utente o ad altri eventi.

Metodi ed eventi avanzati della finestra

Oltre ai popup di base, JavaScript offre una varietà di metodi per interagire con le finestre del browser, migliorando funzionalità e interattività dell'utente.

Ridimensionare e spostare elementi

JavaScript consente il ridimensionamento dinamico e il riposizionamento degli elementi della pagina, il che può essere particolarmente utile nella creazione di applicazioni web responsive e intuitive. (Nota: window.resizeTo() e window.moveTo() esistono per test legacy o in ambienti con restrizioni, ma i browser moderni le limitano fortemente per ragioni di sicurezza. Questo esempio simula il comportamento usando un div con stile. Per elementi UI trascinabili o ridimensionabili, position: absolute è spesso preferibile a relative per garantire calcoli delle coordinate prevedibili.)

<!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>

Aspetti chiave:

  1. Struttura HTML: Include un pulsante e un elemento div con stile simile a una finestra. Il div rappresenta la finestra che "ridimensioneremo" e "sposteremo".
  2. Stile CSS: Definisce le dimensioni e la posizione iniziale della finestra simulata, con transizioni fluide per l'effetto visivo.
  3. Funzione JavaScript: Quando il pulsante viene cliccato, la funzione adjustSimulatedWindow alterna le dimensioni e la posizione della finestra simulata. La variazione di posizione è gestita modificando le proprietà CSS top e left, simulando lo spostamento di una finestra sullo schermo.

Gestire gli eventi della finestra

La gestione degli eventi è fondamentale per la creazione di applicazioni interattive. JavaScript fornisce diversi eventi relativi alle azioni della finestra, come onbeforeunload e onunload, che possono essere usati per eseguire codice in momenti strategici.

<!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>

Aspetti chiave:

  1. Link simulato per l'uscita dalla pagina: Il link con href="#" e un handler onclick che chiama simulatePageLeave(); return false; simula l'effetto del tentativo di uscire dalla pagina. return false; impedisce l'azione predefinita del link, mantenendo l'utente sulla pagina corrente.
  2. Finestra di dialogo di conferma: La funzione simulatePageLeave presenta una finestra di conferma simile a quella che apparirebbe con un effettivo tentativo di abbandono della pagina. Permette agli utenti di decidere se vogliono "uscire" o meno.
  3. Aggiornamenti del messaggio: In base alla scelta dell'utente nella finestra di conferma, il messaggio nel div viene aggiornato per riflettere la scelta, imitando il comportamento che ci si aspetterebbe quando si tenta davvero di lasciare la pagina.
  4. Nota sul comportamento del browser: I browser moderni ignorano le stringhe personalizzate restituite da onbeforeunload e mostrano solo una finestra di conferma predefinita. L'esempio dimostra il trigger dell'evento, ma il testo esatto del prompt è controllato dal browser.
Informazione

Modificare l'innerHTML di un elemento rende le interazioni dell'utente più fluide e meno intrusive. Questo approccio funziona molto bene per siti web interattivi e strumenti didattici.

Chiudere una finestra popup

È importante fornire un meccanismo che consenta agli utenti di chiudere facilmente i popup che crei. Questo migliora l'esperienza utente permettendo loro di controllare la propria interazione con la tua applicazione.

<!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>

Aspetti chiave:

  1. Gestione dello stato: La variabile myPopup è inizialmente impostata a null e viene verificato se è null o se è stata chiusa (myPopup.closed). Questo aiuta a decidere se creare un nuovo popup o portare in primo piano quello esistente.
  2. Duplicazione del contenuto: Assicurandosi che il popup sia correttamente inizializzato o chiuso, si evita il problema della duplicazione del contenuto. Ogni apertura del popup inizia da zero.
  3. Gestione del focus: L'uso di myPopup.focus() garantisce che, se il popup è già aperto, venga portato in primo piano quando si clicca nuovamente su "Open Popup".
Informazione

Testa sempre il comportamento dei popup e dei metodi della finestra su browser e dispositivi diversi per garantire compatibilità e responsività.

Focus e blur su una finestra

Gli eventi focus e blur possono essere usati per rilevare quando una finestra o una pagina acquisisce o perde il focus. Questo può essere utile per mettere in pausa le attività quando l'utente cambia scheda o finestra.

<!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>

Aspetti chiave:

  • Handler degli eventi: handleFocus() e handleBlur() aggiornano il contenuto della pagina e il colore di sfondo in base allo stato di focus della finestra.
  • Feedback visivo: I cambiamenti nel colore di sfondo forniscono un feedback visivo immediato e chiaro sullo stato del focus, migliorando l'esperienza interattiva.

Sicurezza e blocco dei popup

Poiché i popup sono stati storicamente usati in modo improprio, i browser moderni applicano regole rigide. Conoscerle risparmia ore di debug su "perché la mia finestra è null?".

  • Requisito del gesto utente. Un popup si apre solo durante un'azione utente sincrona (clic, pressione di un tasto, tocco). Dopo un await o un setTimeout, il gesto è "consumato" e la chiamata viene bloccata.
  • window.opener e noopener. Quando apri una finestra, la nuova pagina può leggere e persino navigare nell'opener tramite window.opener. Per i link verso siti non attendibili questo rappresenta un rischio di phishing, quindi aggiungi rel="noopener" ai link o passa noopener nella stringa features:
// 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");
  • Rilevare un popup bloccato. Controlla sempre il valore restituito, poiché una chiamata bloccata restituisce 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";
}

Best practice per l'uso di popup e metodi della finestra

  1. Consenso e controllo dell'utente: Assicurati sempre che i popup non disturbino l'esperienza utente. Fornisci agli utenti ampie possibilità di chiudere i popup indesiderati.
  2. Considerazioni sulla sicurezza: Tieni presente le implicazioni di sicurezza del contenuto esterno nei popup. Usa fonti attendibili e connessioni sicure per proteggere i dati degli utenti.
  3. Ottimizzazione delle prestazioni: Usa i popup e i metodi della finestra con parsimonia, poiché possono influire sulle prestazioni della tua applicazione web. Ottimizza l'utilizzo per bilanciare funzionalità ed efficienza delle risorse.

Conclusione

Usare efficacemente i popup JavaScript e i metodi della finestra può migliorare significativamente le funzionalità e l'esperienza utente delle applicazioni web. Seguendo gli esempi e le best practice forniti, gli sviluppatori possono implementare queste funzionalità in modo efficiente e responsabile. Ricorda di dare sempre priorità all'esperienza utente e alla sicurezza in tutte le implementazioni per mantenere l'integrità e l'efficacia delle tue applicazioni web.

Capitoli correlati

Esercitazione

Pratica
Quali dei seguenti sono metodi per mostrare popup in JavaScript?
Quali dei seguenti sono metodi per mostrare popup in JavaScript?
Was this page helpful?