web-dev-qa-db-fra.com

Comment afficher "Etes-vous sûr de vouloir quitter cette page?" quand les changements sont-ils engagés?

Ici, dans stackoverflow, si vous avez commencé à apporter des modifications, vous essayez de naviguer en dehors de la page. Un bouton de confirmation javascript apparaît et demande: "Êtes-vous sûr de vouloir quitter cette page?" bla bla bloo ...

Quelqu'un a-t-il déjà implémenté cela auparavant, comment puis-je suivre que les modifications ont été validées? Je crois que je pourrais le faire moi-même, j'essaie d'apprendre les bonnes pratiques de la part des experts.

J'ai essayé ce qui suit mais cela ne fonctionne toujours pas:

<html>
<body>
    <p>Close the page to trigger the onunload event.</p>
    <script type="text/javascript">
        var changes = false;        
        window.onbeforeunload = function() {
            if (changes)
            {
                var message = "Are you sure you want to navigate away from this page?\n\nYou have started writing or editing a post.\n\nPress OK to continue or Cancel to stay on the current page.";
                if (confirm(message)) return true;
                else return false;
            }
        }
    </script>

    <input type='text' onchange='changes=true;'> </input>
</body>
</html>

Quelqu'un peut-il poster un exemple?

246
Shimmy

Mise à jour (2017)

Les navigateurs modernes considèrent désormais l'affichage d'un message personnalisé comme un danger pour la sécurité et il a donc été supprimé de tous. Les navigateurs affichent désormais uniquement les messages génériques. Puisque nous n’avons plus à nous préoccuper de la définition du message, c’est aussi simple que:

// Enable navigation Prompt
window.onbeforeunload = function() {
    return true;
};
// Remove navigation Prompt
window.onbeforeunload = null;

Lisez ci-dessous pour la prise en charge des navigateurs existants.

Mise à jour (2013)

La réponse originale convient à IE6-8 et FX1-3.5 (ce que nous visions en 2009 au moment de sa rédaction), mais elle est plutôt obsolète à présent et ne fonctionnera pas dans la plupart des navigateurs actuels - il me reste ci-dessous pour référence.

Le window.onbeforeunload n'est pas traité de manière cohérente par tous les navigateurs. Ce doit être une référence de fonction et non une chaîne (comme indiqué dans la réponse originale), mais cela fonctionnera dans les anciens navigateurs, car la plupart des vérifications semblent vérifier si quelque chose est affecté à onbeforeunload (y compris une fonction qui renvoie null).

Vous définissez window.onbeforeunload sur une référence de fonction, mais dans les navigateurs plus anciens, vous devez définir la valeur returnValue de l'événement au lieu de simplement renvoyer une chaîne:

var confirmOnPageExit = function (e) 
{
    // If we haven't been passed the event get the window.event
    e = e || window.event;

    var message = 'Any text will block the navigation and display a Prompt';

    // For IE6-8 and Firefox prior to version 4
    if (e) 
    {
        e.returnValue = message;
    }

    // For Chrome, Safari, IE8+ and Opera 12+
    return message;
};

Vous ne pouvez pas laisser cette confirmOnPageExit faire la vérification et renvoyer null si vous voulez que l'utilisateur continue sans le message. Vous devez toujours supprimer l'événement pour l'activer et le désactiver de manière fiable:

// Turn it on - assign the function that returns the string
window.onbeforeunload = confirmOnPageExit;

// Turn it off - remove the function entirely
window.onbeforeunload = null;

Réponse originale (travaillé en 2009)

Pour l'allumer:

window.onbeforeunload = "Are you sure you want to leave?";

Pour l'éteindre:

window.onbeforeunload = null;

Gardez à l'esprit que ce n'est pas un événement normal - vous ne pouvez pas le lier de manière standard.

Pour vérifier les valeurs? Cela dépend de votre cadre de validation.

Dans jQuery, cela pourrait ressembler à (exemple très basique):

$('input').change(function() {
    if( $(this).val() != "" )
        window.onbeforeunload = "Are you sure you want to leave?";
});
341
Keith

Le onbeforeunload Microsoft-isme est ce qui se rapproche le plus d'une solution standard, mais sachez que la prise en charge du navigateur est inégale. par exemple. pour Opera, il ne fonctionne que dans les versions 12 et supérieures (toujours en version bêta à ce jour).

De plus, pour une compatibilité maximale , vous devez faire plus que simplement renvoyer une chaîne, comme expliqué à la section Mozilla Developer Network .

Exemple: Définissez les deux fonctions suivantes pour activer/désactiver le message de navigation (voir l'exemple de MDN):

function enableBeforeUnload() {
    window.onbeforeunload = function (e) {
        return "Discard changes?";
    };
}
function disableBeforeUnload() {
    window.onbeforeunload = null;
}

Puis définissez un formulaire comme celui-ci:

<form method="POST" action="" onsubmit="disableBeforeUnload();">
    <textarea name="text"
              onchange="enableBeforeUnload();"
              onkeyup="enableBeforeUnload();">
    </textarea>
    <button type="submit">Save</button>
</form>

De cette manière, l'utilisateur ne sera averti de la navigation que s'il a modifié la zone de texte et ne sera pas invité à le faire lorsqu'il soumettra le formulaire.

37
Søren Løvborg

Pour que cela fonctionne dans Chrome et Safari, vous devez le faire comme ceci

window.onbeforeunload = function(e) {
    return "Sure you want to leave?";
};

Référence: https://developer.mozilla.org/en/DOM/window.onbeforeunload

19
sshow

Avec JQuery ce genre de choses est assez facile à faire. Depuis que vous pouvez vous lier à des ensembles.

Son pas assez pour faire le onbeforeunload, vous voulez déclencher la navigation si quelqu'un a commencé à éditer des choses.

18
Sam Saffron

jquery 'beforeunload' a bien fonctionné pour moi

$(window).bind('beforeunload', function(){
    if( $('input').val() !== '' ){
        return "It looks like you have input you haven't submitted."
    }
});
13
Devon Peticolas

C'est un moyen facile de présenter le message si des données sont entrées dans le formulaire et de ne pas afficher le message si le formulaire est soumis:

$(function () {
    $("input, textarea, select").on("input change", function() {
        window.onbeforeunload = window.onbeforeunload || function (e) {
            return "You have unsaved changes.  Do you want to leave this page and lose your changes?";
        };
    });
    $("form").on("submit", function() {
        window.onbeforeunload = null;
    });
})
11
Carl G

pour les nouvelles personnes qui recherchent une solution simple, essayez simplement Areyousure.js

11
lawphotog

Pour développer la réponse de Keith est déjà étonnante :

Messages d'avertissement personnalisés

Pour autoriser les messages d'avertissement personnalisés, vous pouvez l'envelopper dans une fonction comme celle-ci:

function preventNavigation(message) {
    var confirmOnPageExit = function (e) {
        // If we haven't been passed the event get the window.event
        e = e || window.event;

        // For IE6-8 and Firefox prior to version 4
        if (e)
        {
            e.returnValue = message;
        }

        // For Chrome, Safari, IE8+ and Opera 12+
        return message;
    };
    window.onbeforeunload = confirmOnPageExit;
}

Ensuite, appelez simplement cette fonction avec votre message personnalisé:

preventNavigation("Baby, please don't go!!!");

Activer à nouveau la navigation

Pour réactiver la navigation, il vous suffit de définir window.onbeforeunload sur null. La voici, enveloppée dans une petite fonction soignée qui peut être appelée n'importe où:

function enableNavigation() {
    window.onbeforeunload = null;
}

Utiliser jQuery pour lier ceci afin de former des éléments

Si vous utilisez jQuery, cela peut facilement être lié à tous les éléments d'un formulaire comme celui-ci:

$("#yourForm :input").change(function() {
    preventNavigation("You have not saved the form. Any \
        changes will be lost if you leave this page.");
});

Ensuite, pour permettre au formulaire d'être soumis:

$("#yourForm").on("submit", function(event) {
    enableNavigation();
});

Formes modifiées dynamiquement:

preventNavigation() et enableNavigation() peuvent être liés à d'autres fonctions, telles que la modification dynamique d'un formulaire ou le fait de cliquer sur un bouton qui envoie une demande AJAX. Je l'ai fait en ajoutant un élément d'entrée caché au formulaire:

<input id="dummy_input" type="hidden" />

Ensuite, chaque fois que je veux empêcher l'utilisateur de naviguer, je déclenche le changement sur cette entrée pour m'assurer que preventNavigation() est exécuté:

function somethingThatModifiesAFormDynamically() {

    // Do something that modifies a form

    // ...
    $("#dummy_input").trigger("change");
    // ...
}
7
Mike

Ici essaye ça marche à 100%

<html>
<body>
<script>
var warning = true;
window.onbeforeunload = function() {  
  if (warning) {  
    return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";  
    }  
}

$('form').submit(function() {
   window.onbeforeunload = null;
});
</script>
</body>
</html>
3
Braydon

Lorsque l'utilisateur commence à modifier le formulaire, un indicateur booléen est défini. Si l'utilisateur tente ensuite de s'éloigner de la page, activez cet indicateur dans l'événement window.onunload . Si l'indicateur est défini, vous affichez le message en le renvoyant sous forme de chaîne. Renvoyer le message sous forme de chaîne fera apparaître une boîte de dialogue de confirmation contenant votre message.

Si vous utilisez ajax pour valider les modifications, vous pouvez définir le drapeau sur false une fois les modifications validées (c.-à-d. Dans l'événement ajax success.).

2
Kirtan

Les états standard que l'invite peut être contrôlée en annulant l'événement beforeunload ou en définissant la valeur de retour sur valeur non nulle . Il indique également que les auteurs doivent utiliser Event.preventDefault () à la place de returnValue et que le message affiché à l'utilisateur n'est pas personnalisable .

En date du 69.0.3497.92, Chrome n'était pas conforme à la norme. Cependant, il y a un rapport de bogue déposé et un examen est en cours. Chrome requiert que returnValue soit défini par référence à l'objet événement, pas à la valeur renvoyée par le gestionnaire.

Il incombe à l'auteur de suivre si des modifications ont été apportées. cela peut être fait avec une variable ou en s'assurant que l'événement n'est géré que lorsque cela est nécessaire.

window.addEventListener('beforeunload', function (e) {
    // Cancel the event as stated by the standard.
    e.preventDefault();
    // Chrome requires returnValue to be set.
    e.returnValue = '';
});
    
window.location = 'about:blank';
2
Trevor Karjanis

voici mon html

<!DOCTYPE HMTL>
<meta charset="UTF-8">
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="script.js"></script>
</head>

 <body onload="myFunction()">
    <h1 id="belong">
        Welcome To My Home
    </h1>
    <p>
        <a id="replaceME" onclick="myFunction2(event)" href="https://www.ccis.edu">I am a student at Columbia College of Missouri.</a>
    </p>
</body>

Et voici comment j'ai fait quelque chose de similaire en javaScript

var myGlobalNameHolder ="";

function myFunction(){
var myString = Prompt("Enter a name", "Name Goes Here");
    myGlobalNameHolder = myString;
    if (myString != null) {
        document.getElementById("replaceME").innerHTML =
        "Hello " + myString + ". Welcome to my site";

        document.getElementById("belong").innerHTML =
        "A place you belong";
    }   
}

// create a function to pass our event too
function myFunction2(event) {   
// variable to make our event short and sweet
var x=window.onbeforeunload;
// logic to make the confirm and alert boxes
if (confirm("Are you sure you want to leave my page?") == true) {
    x = alert("Thank you " + myGlobalNameHolder + " for visiting!");
}
}
1
Justin

Basé sur toutes les réponses sur ce fil, j'ai écrit le code suivant et cela a fonctionné pour moi.

Si vous ne disposez que de certaines balises input/textarea nécessitant la vérification d'un événement onunload, vous pouvez affecter des attributs de données HTML5 sous la forme data-onunload="true"

pour par exemple.

<input type="text" data-onunload="true" />
<textarea data-onunload="true"></textarea>

et le Javascript (jQuery) peut ressembler à ceci:

$(document).ready(function(){
    window.onbeforeunload = function(e) {
        var returnFlag = false;
        $('textarea, input').each(function(){
            if($(this).attr('data-onunload') == 'true' && $(this).val() != '')
                returnFlag = true;
        });

        if(returnFlag)
            return "Sure you want to leave?";   
    };
});
1
Sagar Gala

Vous pouvez ajouter un événement onchange à la zone de texte (ou à tout autre champ) définissant une variable dans JS. Lorsque l'utilisateur tente de fermer la page (window.onunload), vous vérifiez la valeur de cette variable et affichez l'alerte en conséquence.

1
Makram Saleh

Ce que vous voulez utiliser, c'est l'événement onunload en JavaScript.

Voici un exemple: http://www.w3schools.com/jsref/event_onunload.asp

0
waqasahmed

Cela peut être facilement fait en définissant un ChangeFlag à true, le onChange événement de TextArea. Utilisez javascript pour afficher la boîte de dialogue confirmer basée sur la valeur ChangeFlag. Supprimez le formulaire et accédez à la page demandée si confirmer renvoie true, sinon ne rien faire.

0
simplyharsh