Je souhaite capturer l'événement de fermeture de la fenêtre/du navigateur du navigateur. J'ai essayé ce qui suit avec jQuery:
jQuery(window).bind(
"beforeunload",
function() {
return confirm("Do you really want to close?")
}
)
Mais cela fonctionne aussi sur la soumission de formulaire, ce qui n'est pas ce que je veux. Je veux un événement qui se déclenche uniquement lorsque l'utilisateur ferme la fenêtre.
L'événement beforeunload
se déclenche chaque fois que l'utilisateur quitte votre page pour une raison quelconque.
Par exemple, il sera déclenché si l'utilisateur soumet un formulaire, clique sur un lien, ferme la fenêtre (ou un onglet) ou affiche une nouvelle page à l'aide de la barre d'adresse, du champ de recherche ou d'un signet.
Vous pouvez exclure les envois de formulaire et les liens hypertexte (à l'exception des autres cadres) à l'aide du code suivant:
var inFormOrLink;
$('a').on('click', function() { inFormOrLink = true; });
$('form').on('submit', function() { inFormOrLink = true; });
$(window).on("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})
Pour les versions de jQuery antérieures à 1.7, essayez ceci:
var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });
$(window).bind("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})
La méthode live
ne fonctionne pas avec l'événement submit
. Par conséquent, si vous ajoutez un nouveau formulaire, vous devez également y associer le gestionnaire.
Notez que si un autre gestionnaire d'événements annule la soumission ou la navigation, vous perdrez l'invite de confirmation si la fenêtre est réellement fermée ultérieurement. Vous pouvez résoudre ce problème en enregistrant l'heure dans les événements submit
et click
, et en vérifiant si la beforeunload
se produit plus de quelques secondes plus tard.
Peut-être simplement dissocier le gestionnaire d'événement beforeunload
dans le gestionnaire d'événement submit
du formulaire:
jQuery('form').submit(function() {
jQuery(window).unbind("beforeunload");
...
});
Pour une solution inter-navigateur (testé dans Chrome 21, IE9, FF15), envisagez d'utiliser le code suivant, qui est une version légèrement modifiée du code de Slaks:
var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });
$(window).bind('beforeunload', function(eventObject) {
var returnValue = undefined;
if (! inFormOrLink) {
returnValue = "Do you really want to close?";
}
eventObject.returnValue = returnValue;
return returnValue;
});
Notez que depuis Firefox 4, le message "Voulez-vous vraiment fermer?" n'est pas affiché. FF affiche simplement un message générique. Voir la note dans https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload
window.onbeforeunload = function () {
return "Do you really want to close?";
};
Pour une solution qui fonctionne bien avec des contrôles tiers tels que Telerik (ex: RadComboBox) et DevExpress qui utilisent les balises Anchor pour diverses raisons, envisagez d'utiliser le code suivant, qui est une version légèrement modifiée du code de desm avec un meilleur sélecteur pour soi. ciblage des balises d'ancrage:
var inFormOrLink;
$('a[href]:not([target]), a[href][target=_self]').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });
$(window).bind('beforeunload', function(eventObject) {
var returnValue = undefined;
if (! inFormOrLink) {
returnValue = "Do you really want to close?";
}
eventObject.returnValue = returnValue;
return returnValue;
});
Ma réponse vise à fournir des repères simples.
Voir @ SLaks answer .
$(window).on("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})
Lorsqu'un utilisateur ferme la page (x bouton ou CTRL + W), le navigateur exécute le code beforeunload
donné, mais pas indéfiniment. La seule exception est la boîte de confirmation (return 'Do you really want to close?
) qui attendra la réponse de l'utilisateur.
Chrome : 2 secondes.
Firefox : (ou double-cliquez ou forcez la fermeture)
Edge : (ou double-cliquez)
Explorer 11 : 0 seconde.
Safari : TODO
Ce que nous avons utilisé pour tester ceci:
Ce qu’il fait est d’envoyer autant de demandes qu’il le peut avant que le navigateur ne ferme sa page (de manière synchrone).
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function request() {
return $.ajax({
type: "GET",
url: "http://localhost:3030/" + Date.now(),
async: true
}).responseText;
}
window.onbeforeunload = () => {
while (true) {
request();
}
return null;
}
</script>
</body>
</html>
Sortie de chrome:
GET /1480451321041 404 0.389 ms - 32
GET /1480451321052 404 0.219 ms - 32
...
GET /hello/1480451322998 404 0.328 ms - 32
1957ms ≈ 2 seconds // we assume it's 2 seconds since requests can take few milliseconds to be sent.
J'ai utilisé Slaks answer mais cela ne fonctionnait pas tel quel, car onbeforeunload returnValue est analysé sous forme de chaîne, puis affiché dans la zone de confirmation du navigateur. Donc, la valeur true a été affichée, comme "true".
Juste en utilisant le retour a fonctionné. Voici mon code
var preventUnloadPrompt;
var messageBeforeUnload = "my message here - Are you sure you want to leave this page?";
//var redirectAfterPrompt = "http://www.google.co.in";
$('a').live('click', function() { preventUnloadPrompt = true; });
$('form').live('submit', function() { preventUnloadPrompt = true; });
$(window).bind("beforeunload", function(e) {
var rval;
if(preventUnloadPrompt) {
return;
} else {
//location.replace(redirectAfterPrompt);
return messageBeforeUnload;
}
return rval;
})
Malheureusement, qu’il s’agisse d’un rechargement, d’une nouvelle redirection de page ou de la fermeture du navigateur, l’événement sera déclenché. Une alternative consiste à intercepter l'identifiant déclenchant l'événement. S'il s'agit d'un formulaire, il ne déclenche aucune fonction. S'il ne s'agit pas de l'identifiant du formulaire, faites ce que vous souhaitez faire à la fermeture de la page. Je ne sais pas si cela est également possible directement et fastidieux.
Vous pouvez faire quelques petites choses avant que le client ferme l'onglet. onglet fermer le navigateur javascript/fermer le navigateur mais si votre liste d'actions est longue et que l'onglet se ferme avant la fin, vous êtes impuissant. Vous pouvez l'essayer, mais avec mon expérience, n'en dépendez pas.
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
/* Do you small action code here */
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
jQuery(window).bind(
"beforeunload",
function (e) {
var activeElementTagName = e.target.activeElement.tagName;
if (activeElementTagName != "A" && activeElementTagName != "INPUT") {
return "Do you really want to close?";
}
})
Vous pourriez peut-être gérer OnSubmit et définir un indicateur à vérifier ultérieurement dans votre gestionnaire OnBeforeUnload.
Si votre soumission de formulaire les amène à une autre page (comme je le suppose, d'où le déclenchement de beforeunload
), vous pouvez essayer de modifier la soumission de votre formulaire en un appel ajax. De cette façon, ils ne quitteront pas votre page lorsqu'ils soumettront le formulaire et vous pourrez utiliser votre code de liaison beforeunload
à votre guise.
Mon problème: L'événement 'onbeforeunload' ne serait déclenché que s'il y avait un nombre impair de soumissions (clics). J'ai eu une combinaison de solutions de threads similaires dans SO pour que ma solution fonctionne. bien mon code va parler.
<!--The definition of event and initializing the trigger flag--->
$(document).ready(function() {
updatefgallowPrompt(true);
window.onbeforeunload = WarnUser;
}
function WarnUser() {
var allowPrompt = getfgallowPrompt();
if(allowPrompt) {
saveIndexedDataAlert();
return null;
} else {
updatefgallowPrompt(true);
event.stopPropagation
}
}
<!--The method responsible for deciding weather the unload event is triggered from submit or not--->
function saveIndexedDataAlert() {
var allowPrompt = getfgallowPrompt();
var lenIndexedDocs = parseInt($('#sortable3 > li').size()) + parseInt($('#sortable3 > ul').size());
if(allowPrompt && $.trim(lenIndexedDocs) > 0) {
event.returnValue = "Your message";
} else {
event.returnValue = " ";
updatefgallowPrompt(true);
}
}
<!---Function responsible to reset the trigger flag---->
$(document).click(function(event) {
$('a').live('click', function() { updatefgallowPrompt(false); });
});
<!--getter and setter for the flag---->
function updatefgallowPrompt (allowPrompt){ //exit msg dfds
$('body').data('allowPrompt', allowPrompt);
}
function getfgallowPrompt(){
return $('body').data('allowPrompt');
}
Essayez ceci aussi
window.onbeforeunload = function ()
{
if (pasteEditorChange) {
var btn = confirm('Do You Want to Save the Changess?');
if(btn === true ){
SavetoEdit();//your function call
}
else{
windowClose();//your function call
}
} else {
windowClose();//your function call
}
};
Depuis jQuery 1.7, la méthode .live () est obsolète. Utilisez .on () pour attacher des gestionnaires d’événements. Les utilisateurs d'anciennes versions de jQuery doivent utiliser .delegate () plutôt que .live ()
$(window).bind("beforeunload", function() {
return true || confirm("Do you really want to close?");
});
sur complet ou lien
$(window).unbind();