how to diable window.onbeforeunload alert when timer is timedout - javascript

I have used window.onbeforeunload() to display an alert when the user navigates away from the page and this works fine,
jQuery(window).bind('beforeunload', function (e) {
var message = "Attention:";
e.returnValue = message;
return message;
});
In one of the views in my project I have used a timer.The problem is that,when the timer is timed out an alert is displayed and it is followed by the window.onbeforeunload() alert.
I want only the timer alert and not both to be displayed on timer timeout.
How can I achieve this?

As Shaunak commented, you should before unbind your "hardcoded" beforeunload function definition :
jQuery(window).unbind();
and then redefine it:
jQuery(window).bind('beforeunload', function (e) {
var message = "Attention:";
e.returnValue = message;
return message;
});

to unbind an event, you need a reference to original handler.
please see below.
var func = function(e) {
var message = "Attention:";
e.returnValue = message;
return message;
};
jQuery(window).bind('beforeunload', func);
// Unbind 'beforeunload' after 10 seconds
setTimeout(function() {
jQuery(window).unbind('beforeunload', func);
alert('beforeunload unbound');
}, 10000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Detect Close window event function [duplicate]

I want to capture the browser window/tab close event.
I have tried the following with jQuery:
jQuery(window).bind(
"beforeunload",
function() {
return confirm("Do you really want to close?")
}
)
But it works on form submission as well, which is not what I want. I want an event that triggers only when the user closes the window.
The beforeunload event fires whenever the user leaves your page for any reason.
For example, it will be fired if the user submits a form, clicks a link, closes the window (or tab), or goes to a new page using the address bar, search box, or a bookmark.
You could exclude form submissions and hyperlinks (except from other frames) with the following code:
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;
})
For jQuery versions older than 1.7, try this:
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;
})
The live method doesn't work with the submit event, so if you add a new form, you'll need to bind the handler to it as well.
Note that if a different event handler cancels the submit or navigation, you will lose the confirmation prompt if the window is actually closed later. You could fix that by recording the time in the submit and click events, and checking if the beforeunload happens more than a couple of seconds later.
Maybe just unbind the beforeunload event handler within the form's submit event handler:
jQuery('form').submit(function() {
jQuery(window).unbind("beforeunload");
...
});
For a cross-browser solution (tested in Chrome 21, IE9, FF15), consider using the following code, which is a slightly tweaked version of Slaks' code:
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;
});
Note that since Firefox 4, the message "Do you really want to close?" is not displayed. FF just displays a generic message. See note in https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload
window.onbeforeunload = function () {
return "Do you really want to close?";
};
My answer is aimed at providing simple benchmarks.
HOW TO
See #SLaks answer.
$(window).on("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})
How long does the browser take to finally shut your page down?
Whenever an user closes the page (x button or CTRL + W), the browser executes the given beforeunload code, but not indefinitely. The only exception is the confirmation box (return 'Do you really want to close?) which will wait until for the user's response.
Chrome: 2 seconds.
Firefox: ∞ (or double click, or force on close)
Edge: ∞ (or double click)
Explorer 11: 0 seconds.
Safari: TODO
What we used to test this out:
A Node.js Express server with requests log
The following short HTML file
What it does is to send as many requests as it can before the browser shut downs its page (synchronously).
<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>
Chrome output:
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.
For a solution that worked well with third party controls like Telerik (ex.: RadComboBox) and DevExpress that use the Anchor tags for various reasons, consider using the following code, which is a slightly tweaked version of desm's code with a better selector for self targeting anchor tags:
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;
});
I used Slaks answer but that wasn't working as is, since the onbeforeunload returnValue is parsed as a string and then displayed in the confirmations box of the browser. So the value true was displayed, like "true".
Just using return worked.
Here is my 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;
})
Perhaps you could handle OnSubmit and set a flag that you later check in your OnBeforeUnload handler.
Unfortunately, whether it is a reload, new page redirect, or browser close the event will be triggered. An alternative is catch the id triggering the event and if it is form dont trigger any function and if it is not the id of the form then do what you want to do when the page closes. I am not sure if that is also possible directly and is tedious.
You can do some small things before the customer closes the tab. javascript detect browser close tab/close browser but if your list of actions are big and the tab closes before it is finished you are helpless. You can try it but with my experience donot depend on it.
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
});
https://developer.mozilla.org/en-US/docs/Web/Reference/Events/beforeunload?redirectlocale=en-US&redirectslug=DOM/Mozilla_event_reference/beforeunload
jQuery(window).bind("beforeunload", function (e) {
var activeElementTagName = e.target.activeElement.tagName;
if (activeElementTagName != "A" && activeElementTagName != "INPUT") {
return "Do you really want to close?";
}
})
If your form submission takes them to another page (as I assume it does, hence the triggering of beforeunload), you could try to change your form submission to an ajax call. This way, they won't leave your page when they submit the form and you can use your beforeunload binding code as you wish.
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live()
$(window).bind("beforeunload", function() {
return true || confirm("Do you really want to close?");
});
on complete or link
$(window).unbind();
Try this also
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
}
};
My Issue: The 'onbeforeunload' event would only be triggered if there were odd number of submits(clicks). I had a combination of solutions from similar threads in SO to have my solution work. well my code will speak.
<!--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');
}
Just verify...
function wopen_close(){
var w = window.open($url, '_blank', 'width=600, height=400, scrollbars=no, status=no, resizable=no, screenx=0, screeny=0');
w.onunload = function(){
if (window.closed) {
alert("window closed");
}else{
alert("just refreshed");
}
}
}
var validNavigation = false;
jQuery(document).ready(function () {
wireUpEvents();
});
function endSession() {
// Browser or broswer tab is closed
// Do sth here ...
alert("bye");
}
function wireUpEvents() {
/*
* For a list of events that triggers onbeforeunload on IE
* check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
*/
window.onbeforeunload = function () {
debugger
if (!validNavigation) {
endSession();
}
}
// Attach the event keypress to exclude the F5 refresh
$(document).bind('keypress', function (e) {
debugger
if (e.keyCode == 116) {
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function () {
debugger
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function () {
debugger
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function () {
debugger
validNavigation = true;
});
}`enter code here`
Following worked for me;
$(window).unload(function(event) {
if(event.clientY < 0) {
//do whatever you want when closing the window..
}
});

How to listen to Notification in Javascritpt in HTML page?

I have an html file, When this page is open, in a certain condition, there will be a desktop notification. I want to listen to notification happens, and run some scripts.
<html>
...
<script>
var title = document.title
if (notification happens) {
window.onblur = function() {
document.title = "You got a new msg";
};
}
window.onfocus = function() {
document.title = title;
};
</script>
...
</html>
I there any way to find out if (notification happens)?
You cna listen for .onclick like a proper DOM element, or add an event listener:
notification.addEventListener('click', (e) => {
//you can only access the event (e) in this case
});
or as a click
notification.onclick = e => {
//you can only access the event (e) in this case
}

An alert after closing popup, fine with Chrome and Firefox, but problems with IE

<script>
var openDialog = function(uri, name, options, closeCallback) {
var win = window.open(uri, name, options);
var interval = window.setInterval(function() {
try {
if (win == null || win.closed) {
window.clearInterval(interval);
closeCallback(win);
}
}
catch (e) {
}
}, 1000);
return win;
};
var test = function() {
alert(bye);
};
openDialog("//google.com", "popup", "scrollbars=no", test);
</script>
This is code to show an alert after closing popup. It works fine in Chrome and Firefox, but has a problem in IE. In IE, the popup opens, and before closing it, the alert comes up. How can I fix it? I want to show the alert after closing the popup. Thank you.
You shouldn't probe objects to see if they exist every x seconds. Attach events with a callback function, then you only fire an event once, when you actually need to and not a million times before.
Try:
var openDialog = function(uri, name, options, closeCallback) {
var win = window.open(uri, name, options);
win.addEventListener("onunload", test);
};
var test = function() {
alert(bye);
};
this should fire your alert when the window closes, enjoy

window.onbeforeunload executed on page refresh instead of on page close

I'm using window.onbeforeunload to pop up a confirm dialog when a close event occurs, but the confirm dialog appears on page refresh and doesn't execute on page close.
Here's the JavaScript code:
<script language="JavaScript">
window.onbeforeunload = confirmWinClose();
function confirmWinClose() {
var confirmClose = confirm('Close?');
return confirmClose;
}
</script>
I tried it on Chrome, Firefox and Internet Explorer.
PROBLEM WITH YOUR CODE:
the function will be called when you refresh, because on refresh the page is unloaded and then reloaded.
in your solution, you should also note that you are not assigning a function to window.onbeforeunload but you are assigning the return value of the function when you write
window.onbeforeunload = confirmWinClose();
which might also execute the function (based on where you place it in the javascript) whenever the assignment is done. For e.g.
function confirmWinClose() {
var confirmClose = confirm('Close?');
return confirmClose;
}
window.onbeforeunload = confirmWinClose();
the above code will execute the confirmWinClose function whenever this js is loaded.
(not your case as you have defined the function after call, so won't be executed on load, but you should remember this)
SOLUTION:
the below solution is working for close also
instead of your solution, i tried this
JS:
window.onbeforeunload = function() {
var confirmClose = confirm('Close?');
return confirmClose;
}
or
window.onbeforeunload = confirmWinClose; //note the absence of calling parantheses
function confirmWinClose() {
var confirmClose = confirm('Close?');
return confirmClose;
}
this works as expected.
also note that you should return from the onbeforeunload explicitly.
even if you have to call a function, you should do
<script>
window.onbeforeunload = function(e) {
callSomeFunction();
return null;
};
</script>
No full solution, but you can intercept the F5 key (not intercepted if the user click on the refresh browser button...)
var isRefresh = false;
// with jquery
$(function() {
$(document).on("keydown", function(e) {
if (e.which === 116)
{
isRefresh = true;
}
});
});
window.onbeforeunload = function() {
if (! isRefresh)
{
return confirm ('Close ?');
}
return false;
};
Since you anyway only want to display your text, What just using the onbeforeunload as it is expected just return the string?
<script language="JavaScript">
window.onbeforeunload = confirmWinClose;
function confirmWinClose() {return "close?";}
</script>
Try this it will work. You were assigning the method to onload that need to execute when it event occur so its need to be like object. refer link for better explanation - var functionName = function() {} vs function functionName() {}
window.onbeforeunload = confirmWinClose;
function confirmWinClose () {
var confirmClose = confirm('Close?');
return confirmClose;
};

window.onbeforeunload may fire multiple times

Just because you don't see use for a feature doesn't mean it isn't useful.
The Stack Exchange network, GMail, Grooveshark, Yahoo! Mail, and Hotmail use the onbeforeunload prompt to prevent/warn users that they are leaving a page after they have begun editing something. Oh yah, nearly every single desktop program that accepts saveable user-input data utilizes this prompt-user-before-leaving UX pattern.
I have a function which behaves similarly to this one:
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true){
return "Are you sure you want to leave this page?";
}
}
When a user attempts navigates away from the page the browser presents them with the option to leave or stay on the page. If the user selects the "Leave this page option" and then they quickly click on a link again before the page unloads completely the dialog fires again.
Are there any foolproof solutions to this problem?
Note: The following NOT the solution:
var alreadyPrompted = false;
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true && alreadyPrompted === false){
alreadyPrompted = true;
return "Are you sure you want to leave this page?";
}
}
because the user might select the "Stay on the page" option which would cause future onbeforeunloads to stop working.
I think you could accomplish this with a timer (setInterval) that starts in the onbeforeunload callback. Javascript execution will be paused while the confirm dialog is up, then if the user cancels out the timed function could reset the alreadyPrompted variable back to false, and clear the interval.
Just an idea.
Ok I did a quick test based on your comment.
<span id="counter">0</span>
window.onbeforeunload = function () {
setInterval(function () { $('#counter').html(++counter); }, 1);
return "are you sure?";
}
window.onunload = function () { alert($('#counter').html()) };
In between the two callbacks #counter never got higher than 2 (ms). It seems like using these two callbacks in conjunction gives you what you need.
EDIT - answer to comment:
Close. This is what i was thinking
var promptBeforeLeaving = true,
alreadPrompted = false,
timeoutID = 0,
reset = function () {
alreadPrompted = false;
timeoutID = 0;
};
window.onbeforeunload = function () {
if (promptBeforeLeaving && !alreadPrompted) {
alreadPrompted = true;
timeoutID = setTimeout(reset, 100);
return "Changes have been made to this page.";
}
};
window.onunload = function () {
clearTimeout(timeoutID);
};
I have encapsulated the answers from above in an easy to use function:
function registerUnload(msg, onunloadFunc) {
var alreadPrompted = false,
timeoutID = 0,
reset = function() {
alreadPrompted = false;
timeoutID = 0;
};
if (msg || onunloadFunc) { // register
window.onbeforeunload = function() {
if (msg && !alreadPrompted) {
alreadPrompted = true;
timeoutID = setTimeout(reset, 100);
return msg;
}
};
window.onunload = function() {
clearTimeout(timeoutID);
if (onunloadFunc) onunloadFunc();
};
} else { // unregister
window.onbeforeunload = null;
window.onunload = null;
}
}
To register use:
registerUnload("Leaving page", function() { /* unload work */ });
To unregister use:
registerUnload();
Hope this helps ..

Categories