Trigger event when user clicks the browsers back button - javascript

Is it possible with jquery to trigger a function when the user clicks the browsers back button.
I have a lightbox/widget that when open fills the window when it is open. There is a close button etc but this would be good if this closed if a user hit the back button by mistake.
I have this so far but the function doesnt seem to run at all
$(window).on("navigate", function (event, data) {
event.preventDefault();
console.log('BACK PRESSED');
var direction = data.state.direction;
if (direction === 'back') {
if(widgets.full_active){
$('.close', widgets.active_widget).click();
event.preventDefault();
console.log('CLOSE THIS');
}
}
if (direction === 'forward') {
// do something else
}
});
By not running this line at the start of the function event.preventDefault(); should mean the page never changes

Usually, I do this using the native JavaScript API from the browser, like described here: Manipulating the Broser History.
With jQuery, I see people usually using this plugin: History.js, although I have no idea what is it's status.
The event you're looking for is onpopstate.
A popstate event is dispatched to the window every time the active
history entry changes between two history entries for the same
document.

Related

Logout webpage when click on refresh button

I am developing a website. Where I need to logout the page when one try to refresh the page.
I got the code for logout when one click on f5 for refresh and also I got the code for disable right click on the page. but I dont know how to prevent the refresh button of browser or logout when I press refresh button. I searched many sites. But didn't get an answer.
The code I gor for F5 key is
function fkey(e){
e = e || window.event;
if( wasPressed ) return;
if (e.keyCode == 116) {
alert("f5 pressed");
wasPressed = true;
}else {
alert("Window closed");
}
}
Can anyone please help me for the issue with refresh button?
I think it will work
$("*").keypress(function(e)
{
if (e.keyCode == 116) {
e.preventDefault();
}
});
Try this:
window.onbeforeunload = function(e){
//call logout process here
}
onbeforeunload is an event that fires when a window is about to unload its resources. The document is still visible and the event is still cancelable, in other words, whenever you refresh or close a page it fires an event 'onbeforeunload'. When this event returns a non-void value, the user is prompted to confirm the page unload. In most browsers, the return value of the event is displayed in this dialog.
Reference: https://developer.mozilla.org/en-US/docs/WindowEventHandlers.onbeforeunload
window.onbeforeunload = function(e){
//call logout process here
}
Any custom declaration on OnBeforeUnload will not be executed as the support is removed from the code. So, the above solution will not work for Chrome.
Instead, use HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

JQuery / dirty forms / window.onbeforeunload only triggered after link selection

I'm trying to implement a warning for the users in case they are leaving the form without saving.
The warning dialog works as expected but with the only exception that when the user chooses to 'Stay on Page', the selected side menu entry changed to the one the user clicked on (form is the same).
How can I make sure that the same menu item is still selected once the user chooses to 'Stay on Page'?
var warnMessage = "Unsaved changes. Do you really want to leave the page?";
$(document).ready(function () {
$('a.k-link').on('click', function () {
window.onbeforeunload = function () {
if (isDirty) return warnMessage;
}
});
});
You might find it easier (and possibly more consistent across browsers) to use a confirm prompt (remember, it's a blocking dialog).
<script>
var warnMessage = "Unsaved changes. Do you really want to leave the page?";
$('a.k-link').on('click', function (e) {
if (isDirty && !confirm(warnMessage)) {
e.preventDefault();
}
});
</script>
There are at least two reasons to avoid onbeforeunload:
The spec doesn't require a browser to display the message you
provide, and not all browsers do, and
the correct event is actually beforeunload
You can and should handle this event through window.addEventListener() and the beforeunload event. More documentation is available there. (MDN)
I'm just guessing, since the Kendo UI scripts aren't exactly fun to read through, but the 'selected' class is getting applied because a navigation event was started, even though you cancel it; the Kendo script is probably just listening for a successful click. onbeforeunload and beforeunload both happen after the click event has resolved (AFAIK, anyway).
Following worked for me (adding e.stopPropagation):
$('a.k-link').on('click', function (e) {
if (isDirty && !confirm(warnMessage)) {
e.preventDefault();
e.stopPropagation();
} });
or by returning false:
$('a.k-link').on('click', function (e) {
if (isDirty && !confirm(warnMessage)) {
return false;
} });

How to trigger onbeforeunload with back button in an ajax based application?

I have an ajax based application (ie no page 'reloads` when getting new data).
Initially I wanted to find a way to prevent navigation when unsaved data was present on a form.
I came across window.onbeforeunload.
That didn't work when clicking a links (where content is loaded via ajax and pop/push state changes the url).
I added some handling of the a links but need to use the default window.onbeforeunload to cover the standard means of leaving a page (ie manually entering a new URL or using the back/forwards buttons).
The code below works for:
a links
page refresh
manually entering a new url
But is not triggering window.onbeforeunload when using the back button (in Chrome and Firefox).
Is there something awry with the implementation below or is window.onbeforeunload not meant to be triggered when using the back button?
var save_state = true;
// on entering data into an input field, the save button fades in
// and the save_state changes
$(document).on('keypress', '.class1 input', function() {
if (save_state) {
$(".save_button").fadeIn();
save_state = false;
};
// bind the click event to 'a' (overiding normal link behaviour)
$( "a" ).bind( "click", function(e) {
if (save_state == false) {
e.preventDefault();
alert("Save before leaving.");
// stop the other 'a' bound handlers from being triggered
e.stopPropagation();
return;
}
});
// also cover standard actions when user tries to leave page
// (back/forward or entering a new url manually etc)
window.onbeforeunload = function() {
return 'Save before leaving.';
};
});
// when clicking save, fade out the button and revert the save_state
$(document).on('click', '.save_button button', function(e) {
e.preventDefault();
$(this).parent().fadeOut();
save_state = true;
// 'unbind' onbeforeunload
window.onbeforeunload = null;
});
Edit:
After reading this post, I think it is based on the ajax nature of the app:
As long as you stay within your app, because it's a single-page app,
it doesn't by definition unload, so there's no beforeunload event.
So I think I may need to look at other ways to trigger the event on back/forwards buttons.
I looked in to triggering window.unload on popstate but didn't have any luck with that.
I ended up changing the logic so that as soon as changes were made, they were saved in the database.
I was using selectize.js for the form input handling and just added some extra calls to it.
In selectize.js (here):
if ($target.hasClass('create')) {
self.createItem();
} else {
value = $target.attr('data-value');
became:
if ($target.hasClass('create')) {
self.createItem();
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
} else {
value = $target.attr('data-value');
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
AND (here):
while (values.length) {
self.removeItem(values.pop());
}
self.showInput();
became:
while (values.length) {
self.removeItem(values.pop());
}
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
self.showInput();
And in my own script, the prompt for deleting selectize.js items stayed the same:
onDelete: function(values) {
confirm(values.length > 1 ? 'Are you sure you want to remove these ' + values.length + ' items?' : 'Are you sure you want to remove "' + values[0] + '"?');

Capturing result of window.onbeforeunload confirmation dialog

Is there a way to capture to result of the window.onbeforeunload confirmation dialog like the one below from Stack Overflow (this happens when leaving the 'Ask Question' page without posting the question)?
This is how it appears in Chrome, I believe it's slightly different in other browsers, but you always have some form of yes/no buttons.
Presumably if they're still on the offending page after the event has been triggered they chose to stay and you could probably figure this out by watching the sequence of js. However I would like to know how to determine if they clicked "Leave this page"?
I've implemented this like below:
// concept taken from SO implementation
function setConfirmUnload(showMessage, message) {
window.onbeforeunload = showMessage ? (message ? message : "this is a default message") : null;
}
// pseudo code
listen to changes on inputs
if any inputs fire a change event
call setConfirmUnload(true, 'My warning message')
note I'm using jQuery within my site.
I'm essentially trying to implement a Gmail like drafting implementation, wherein if a user leaves a page with a form they've made changes to without saving they're warmed with a similar dialog. If they choose to discard they're changes and leave the page, I need to clean up some temporary records from the database (I'm thinking an AJAX call, or simply submitting the form with a delete flag) then sending them on their way.
My question also relates to:
jQuery AJAX call in onunload handler firing AFTER getting the page on a manual refresh. How do I guarantee onunload happens first?
You can have the exit confirmation using window.onbeforeunload but there isn't a way to find out which button the user clicked on.
To quote an earlier response from jvenema from this thread:
The primary purpose for the
beforeunload is for things like
allowing the users the option to save
changes before their changes are lost.
Besides, if your users are leaving,
it's already too late [...]
How about this:
$( window ).bind( 'beforeunload' , function( event ) {
setTimeout( function() {
alert( 'Hi againe!' );
} );
return '';
} ).bind( 'unload', function( event ) {
alert( 'Goodby!' );
} );
Late to the party, but I found the following code (in TypeScript) to be a decent way to detect if the person clicked on 'Ok' on that confirmation dialogue window.
public listenToUnloadEvents(): void {
window.addEventListener('beforeunload', (e) => {
const confirmationMessage = '\o/';
(e || window.event).returnValue = confirmationMessage; // Gecko + IE
return confirmationMessage; // Webkit, Safari, Chrome etc.
});
window.addEventListener('unload', () => {
this.sendNotification(Action.LEFT)
});
}
I'm not sure how much time you have to run code in the unload event, but in this instance, I am sending a notification through Socket.io, so it's very quick at completing.
As for detecting the cancel on that notification, as someone else mentioned, creating a global variable like let didEnterBeforeUnload = false could be set to true when the beforeunload event fires. After this, by creating the third event, like so (again, in TypeScript), you can infer the user pressing cancel
window.addEventListener('focus', (e) => {
if (didEnterBeforeUnload) {
console.log('pressed cancel')
}
didEnterBeforeUnload = false
});
As a side-note though, these events won't (iirc) fire unless you have interacted with the page. So make sure to click or tap into the page before trying to navigate away during your testing.
I hope this helps anyone else out there!

Way to know if user clicked Cancel on a Javascript onbeforeunload Dialog?

I am popping up a dialog box when someone tries to navigate away from a particular page without having saved their work. I use Javascript's onbeforeunload event, works great.
Now I want to run some Javascript code when the user clicks "Cancel" on the dialog that comes up (saying they don't want to navigate away from the page).
Is this possible? I'm using jQuery as well, so is there maybe an event like beforeunloadcancel I can bind to?
UPDATE: The idea is to actually save and direct users to a different webpage if they chose cancel
You can do it like this:
$(function() {
$(window).bind('beforeunload', function() {
setTimeout(function() {
setTimeout(function() {
$(document.body).css('background-color', 'red');
}, 1000);
},1);
return 'are you sure';
});
});
The code within the first setTimeout method has a delay of 1ms. This is just to add the function into the UI queue. Since setTimeout runs asynchronously the Javascript interpreter will continue by directly calling the return statement, which in turn triggers the browsers modal dialog. This will block the UI queue and the code from the first setTimeout is not executed, until the modal is closed. If the user pressed cancel, it will trigger another setTimeout which fires in about one second. If the user confirmed with ok, the user will redirect and the second setTimeout is never fired.
example: http://www.jsfiddle.net/NdyGJ/2/
I know this question is old now, but in case anyone is still having issues with this, I have found a solution that seems to work for me,
Basically the unload event is fired after the beforeunload event. We can use this to cancel a timeout created in the beforeunload event, modifying jAndy's answer:
$(function() {
var beforeUnloadTimeout = 0 ;
$(window).bind('beforeunload', function() {
console.log('beforeunload');
beforeUnloadTimeout = setTimeout(function() {
console.log('settimeout function');
$(document.body).css('background-color', 'red');
},500);
return 'are you sure';
});
$(window).bind('unload', function() {
console.log('unload');
if(typeof beforeUnloadTimeout !=='undefined' && beforeUnloadTimeout != 0)
clearTimeout(beforeUnloadTimeout);
});
});
EDIT: jsfiddle here
Not possible. Maybe someone will prove me wrong... What code do you want to run? Do you want to auto-save when they click cancel? That sounds counter-intuitive. If you don't already auto-save, I think it makes little sense to auto-save when they hit "Cancel". Maybe you could highlight the save button in your onbeforeunload handler so the user sees what they need to do before navigating away.
I didn't think it was possible, but just tried this idea and it works (although it is some what of a hack and may not work the same in all browsers):
window.onbeforeunload = function () {
$('body').mousemove(checkunload);
return "Sure thing";
};
function checkunload() {
$('body').unbind("mousemove");
//ADD CODE TO RUN IF CANCEL WAS CLICKED
}
Another variation
The first setTimeout waits for the user to respond to the browser's Leave/Cancel popup. The second setTimeout waits 1 second, and then CancelSelected is only called if the user cancels. Otherwise the page is unloaded and the setTimeout is lost.
window.onbeforeunload = function(e) {
e.returnValue = "message to user";
setTimeout(function () { setTimeout(CancelSelected, 1000); }, 100);
}
function CancelSelected() {
alert("User selected stay/cancel");
}
window.onbeforeunload = function() {
if (confirm('Do you want to navigate away from this page?')) {
alert('Saving work...(OK clicked)')
} else {
alert('Saving work...(canceled clicked)')
return false
}
}
with this code also if user clicks on 'Cancel' in IE8 the default navigation dialog will appear.

Categories

Resources