Following the answer here , I have the code below:
.directive('confirmOnExit', function($window) {
return {
scope: {},
link: function(scope) {
var message = "Changes you made may not be saved.";
$window.onbeforeunload = function(){
return message;
};
scope.$on('$locationChangeStart', function(event) {
if(!$window.confirm("Do you want to leave this page? "+message))
event.preventDefault();
});
scope.$on('$destroy',function(){
$window.onbeforeunload = null;
});
}
};
})
On Chrome, everything is fine. However, on Firefox, almost every time I click the button of the confirm dialog, the error occurs:
Error: [$rootScope:inprog] $digest already in progress
The solutions I found online mostly suggest to use $timeout
. However, event.preventDefault()
inside a $timeout
function seems not preventing URL change. What should I do?
I just ran into this same problem. For me, calling confirm causes an error in firefox and IE. To get around it, I prevent default immediately if there's a message to show, and run the confirm in a timeout. Then, if the user clicks "leave page", I clear the onbeforeunload and use the $location service to set the url again. If your app is a single page app, $locationChangeStart will be called on the first page load, so you'll want to add in a flag at the top like: if (!hasLoaded) { hasLoaded = true; return; }
if (!hasLoaded) { hasLoaded = true; return; }
$rootScope.$on('$locationChangeStart', function (e, newUrl, oldUrl) {
// Call the function and show the confirm dialogue if necessary
if ($window.onbeforeunload) {
let message = $window.onbeforeunload();
if (message) {
// Since we're going to show a message, cancel navigation
e.preventDefault();
$timeout(() => {
if (confirm(message)) {
// User chose not to stay. Unregister the function so that it doesn't fire again.
$window.onbeforeunload = undefined;
// Run the url again. We've cleared onbeforeunload, so this won't create a loop
$location.url(newUrl.replace($window.location.protocol + '//' + $window.location.host, ''));
}
});
}
}
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.