I know how to display an alert to the user if they attempt to navigate away from the current page asking them if they are sure they wish to do so but I was wondering if there is a way to display this alert ONLY when the window / tab is being closed?
I'd like to only have the confirmation display when the window or tab is being closed, not when the user clicks a link.
Not possible.
the only thing close is the onbeforeunload event, but there isn't a difference (to javascript) between a closed window/tab or a navigation to another page.
Follow-up:
I suppose you could attach a click handler to every anchor on the page and use a "dirty" flag, but that's really hack-ish. something like (forgive me, but using jquery for simplicity):
(function(){
var closingWindow = true;
$('a').on('click', function(){
if (this.href == /* on-domain link */){
closingWindow = false;
}
});
$(window).on('beforeunload',function(){
if (closingWindow){
// your alert
}
});
})();
but that's about as close as you're going to get. note: this isn't going to help if another javascript function uses window.location, etc.
You cannot differentiate between the two.
window.onbeforeunload is triggered immediately before the browser unloads its resources. You do not know the reason for the unload, only that it's about to occur:
From the MDN:
An event that fires when a window is about to unload its resources.
The document is still visible and the event is still cancelable.
How about doing something like this?
Have a global variable set to false (i.e. var hasCLickedLink = false;)
On all your links (<a>), attach an event handler that sets the variable to true
On onbeforeunload, check the value of the variable to see if a link has been clicked or not. If it is still false, then they haven't clicked a link so give them the alert.
You need to explicitly specify events for which you don't want to show confirmation dialogue box.
var validNavigation = 0;
function bindDOMEvents() {
// Attach the event keypress to exclude the F5 refresh
$(document).keydown(function(e)
{
var key = e.which || e.keyCode;
if (key == 116)
{
validNavigation = 1;
};
});
// Attach the event click for all links in the page
$("a").bind("click", function()
{
validNavigation = 1;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function()
{
validNavigation = 1;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function()
{
validNavigation = 1;
});
};
$(document).ready(function()
{
bindDOMEvents();
window.onbeforeunload = function () {
console.log(validNavigation);
if (validNavigation == '1')
{
console.log("No Alert.. Continue");
}
else
{
return false;
}
};
});
This solution worked for me in Firefox with Violentmonkey.
It is used like most of all window.onbeforeunload and check if left mouse button was pressed. So if pressed, this mean, click at free space or link opens - not closing tab.
function DetectBrowserExit()
{
if (butpres == 0) {
//your action before closing tab, alert not showing
}
}
window.onbeforeunload = function(){ DetectBrowserExit(); }
// the key is pressed, then when window.onbeforeunload - link is opening, so, tab not closing
document.addEventListener('mousedown',function(e){
if (e.which == 1) { //1-lbutton 2-mb 3-rb
//e.preventDefault();
butpres = 1
setTimeout(function() {
butpres = 0 //if after 3 seconds the script still works then the link has not been clicked, clear the click and continue to catch new clicks
//alert(butpres);
}, 3000); //Two seconds will elapse and Code will execute.
//alert(butpres);
//command_lock();
}
},false);
Related
I'm adding an event listener for onbeforeunload that prompts a confirmation message when the user tries to leave the page.
Unfortunately, I don't want the confirmation message to appear when the user tries to reload the page.
How do I do this?
Here's what I have so far:
window.onbeforeunload = function() {
return "";
}
It's completely possible1.
You can listen for the keydown event and check whether the user reloaded the page via the shortcut Ctrl + R. If so, you can set a variable (in our case, isReload) to true and set a timeout to set it back to false after, say, 100 milliseconds.
When the onbeforeunload event fires, check whether isReload is true. If it is, return null to allow the browser to close. Otherwise, return "" to prompt a confirmation.
Demo:
var isReload = false;
document.addEventListener('keydown', function(e){
if(e.ctrlKey && e.keyCode == 82){
isReload = true;
setTimeout(function(){isReload = false}, 100);
}
})
window.onbeforeunload = function(){
if(!isReload){
return "";
}else{
return null;
}
}
1 This only works for the shortcut. You can't differentiate between closure/reload if the user manually clicks the reload button
I want to make sure when a user is on the page.
Hence, when a user clicks on another window (looses focus) or changes tab, I should stop playing video on my page.
The problem is trying to do both simultaneously.
For example, through this JS plugin (JQuery Visbility), I am able to check whether the tab/window of my page is open.
Here's how it's doing it:
$(document).on({
'show': function() {
console.log('The page gained visibility; the `show` event was triggered.');
},
'hide': function() {
console.log('The page lost visibility; the `hide` event was triggered.');
}
});
But it can't detect whether the page has focus or not. For example, the page might be open, but I may be opening another window separately and keeping my focus there.
The following code takes care of that (taken from here):
function check()
{
if(document.hasFocus() == lastFocusStatus) return;
lastFocusStatus = !lastFocusStatus;
statusEl.innerText = lastFocusStatus ? 'with' : 'without';
}
window.statusEl = document.getElementById('status');
window.lastFocusStatus = document.hasFocus();
check();
setInterval(check, 200);
Now, I am trying to do both simultaneously. Is it possible?
You can add event listeners for the window's focus and blur events.
var hasFocus = true;
$(window).focus(function(){
hasFocus = true;
});
$(window).blur(function(){
hasFocus = false;
});
//check the hasFocus variable to see if the window has focus
I have a parent div content_div which contain form elements inside a table where user selects multiple row elements(clickable rows),download link elements etc.
I have a warning pop up for the user changes done and then try to refresh without clicking save button.
When I select a row and tried to click a download link inside that row,I dont need to show the warning popup.I have the following code but its not working.
If I dont select any rows and tried to click any download links,its not showing any popup,means thats fine.
If I select any rows and then try to click any download links,its showing me the popup which is wrong in my case.
If a user clicks on some other links outside my #content_div,its showing the popup which is true for me.
$(function() {
var formmodified = 0;
//click event for each row inside the table
$(".course_row").click(function(e) {
-- -- -
formmodified = 1; //setting the variable to 1 means user
has changed something inside the page
});
//when form submits
$("#submit").click(function() {
formmodified = 0; //assuming that form is saved after form change
});
//function for warning popup
window.onbeforeunload = confirmExit;
function confirmExit() {
var element_clicked = 0;
//#content_div is the main parent which contain the entire
contents.
$('#content_div').children().on('click', function(e) {
console.log('clicked');
element_clicked = 1; //means the clicked element is inside the #content_div which can be a link or other things
});
console.log(element_clicked);
EDIT: I am always getting element_clicked value as 0 when I click any element inside the div.The value 'clicked'
is showing.I dont know why the value
for the variable is not setting to 1
if (element_clicked) {
//element_clicked = false;
return; // abort beforeunload
} else {
if ((!element_clicked) && (formmodified == 1)) {
return "The selected courses are not saved.
Do you wish to leave the page ? ";
}
}
}
});
Please help me in this case.Thanks in advance
Just add click() event to anchor elements and unbind onbeforeunload event.
$("a").on('click', function() {
window.onbeforeunload = null;
});
This is just an example. You can add a class or id to the selector so that the event is unbinded only when clicked on a specific anchor tag.
For example
$("#content_div a").on('click', function() {
window.onbeforeunload = null;
});
EDIT
If you want to add onbeforeunload to refresh, you either have to do it when any change is trriggered ir just add event when F5 button is pressed.
To be honest I think that first solution is better, necause then even if user clicks refresh button in a browser the popup will come out.
So you would have to change your functionality.
If you do not want to. Here is a quick add to F5 button.
$(document.body).on("keydown", this, function (event) {
if (event.keyCode == 116) {
window.onbeforeunload = true;
}
});
SCENARIO: I just want to warn user on window change; so I've used jQuery's window blur & JavaScript's confirm dialogue box. When user will click OK button the application will redirect to another page & when user will click CANCEL button nothing will happen. He can continue his work on the same page.
ISSUE: OK button is working perfectly but when I click on the CANCEL button, the browser keeps on regenerating the dialogue box. How do I stop that?
CODE:
$(window).blur( function (e) {
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
if (closeWindow) {
// redirect to another page
}
else {
// do nothing.
}
});
As #ROAL explained, the first blur event is because of actual blur, and rest are because of the browser trying to move away from the tab. A simple solution for this would be to use a flag to distinguish between the user generated event and the browser generated event. Give this a try:
var manualCancellation = false;
$(window).blur( function (e) {
if(!manualCancellation ){
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
console.log(e);
if (closeWindow) {
// redirect to another page
}
else {
manualCancellation = true;
// do nothing.
}
} else {
// Reset the value of manualCancellation so that the event is fired the next time.
manualCancellation = false;
}
});
I'm using the following function to prevent double submissions:
$("#form").submit(function () {
var form = $(this);
form.find("input[type=submit]").attr("disabled", "disabled")
form.find("input[type=submit]").attr("value", "Processing");
});
It works fine, but then I have the following code which triggers an alert to avoid accidentally leaving the page:
function goodbye(e) {
if(!e) e = window.event;
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = '¿DO YOU REALLY WANT TO LEAVE THIS PAGE?'; //This is displayed on the dialog
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
}
window.onbeforeunload=goodbye;
The problem is if the user clicks submit and the realizes he didnt want to leave the page and clicks on stay on this page instead, the submit button is still disabled.
How could I re-enable it upon clicking stay on this page?
Thanks!
The button problem
You want to disable and enable the submit button so you know you going to touch the same kind of function and object twice, it is better to make advantage out of this in a function
function disableSubmit(form, enabled){
var submit = form.find("input[type=submit]"),
dataVar = enabled !== true ? "processing-message" : "send-message",
message = submit.data(dataVar);
submit.prop('disabled', (enabled !== true) );
submit.val(message);
}
I could make it even more generic for using it on each form. But the message in the button will display whatever you put in the data-attribute.
Cancel Submit
There is a problem with cancellation of an onbeforeunload event; there is no callback for it. The solution I came with is using a timeout. Since you don't know if the person canceled or not, I think 2 seconds is enough for the page to submit.
You have to have 2 seconds patient to get the submit button enabled again. But you can adjust it all you want of course
if (e.stopPropagation) {
setTimeout(function () {
disableSubmit(formObject, true);
}, 2000);
e.stopPropagation();
e.preventDefault();
}
The JSFiddle example