Lets say I'm trying to do the following:
window.onunload = handleOnClose;
function handleOnClose()
{
logout();
// alert('You have been signed out.');
}
It goes into the handleOnClose if I use the alert function. I don't want to alert any messages on unload. But it doesn't seem to go in the handleOnClose function at all if I remove the alert function.
Add return ""; maybe ?:
window.attachEvent( "onunload", function(event) {
this_function_works(); // must be synchronous
event.preventDefault ? event.preventDefault() : event.returnValue = false;
});
And make sure logout() is executing before page closes. Meaning, you are not trying to do AJAX calls here, or submit forms. You can set or clean cookies or localStorage.
Related
I try to run a loop method on a web page (Facebook) like this:
function loopRefresh () {
console.log("loop refresh method call");
if (shallRefresh){
setTimeout(function(){
loopRefresh()
//Do something here
}, 5000);
} else {
setTimeout(function(){
loopRefresh()
//Do something different here
}, 5000);
}
}
Now so far so good, everything works and the method is called every 5th second. The problem is that when the user clicks the home button:
the page gets reloaded because of the anchor tag and the href, even though it does not refer to a new page.
This breaks the loop.
I already added this function as onclick event to the Home Button:
function homeRefresh() {
shallRefresh = true;
//setTimeout(function(){
// Do the same thing here as in the true case in the loopRefresh method
// }, 2000);
}
I originally just wanted to make the setTimeout call in here, so that the callback function gets executed after the user clicked the button, without the loopRefresh method. But I thought I could solve the problem by passing the variable, which also doesn't work.
Use event.preventDefault() on function starting. like,
function homeRefresh() {
event.preventDefault(); // here..
shallRefresh = true;
//setTimeout(function(){
// Do the same thing here as in the true case in the loopRefresh method
// }, 2000);
}
event.preventDefault() will prevent the default action of the hyperlink.
NOTE: You cannot continue a javascript function after a page reload.
In this coding example the function logout() won't execute all it's async calls and won't wait till they are finished – instead page is unloading before, because the return of the beforeunload event triggers unloading the page.
$(window).on('beforeunload', function(event) {
event.preventDefault();
logout();
return;
});
What I want to try is that the event function returns AFTER several asynchronous calls in logout() are finished.
EDIT: My goal is NOT to show an alert with this! I only want to execute some code before the page is unloaded. The logout function could contain ajax requests and jQuery animations with some duration that needs to be finished.
I tried with callbacks, but end up with this, what isn't the desired result since it's returning to the callback, not to the event function.
$(window).on('beforeunload', function(event) {
event.preventDefault();
logout(function(x) { return; });
});
Since everything executed on the page would become invalid when the page is unloaded, you can't depend on the page itself to complete the async call.
One wordaround for chrome extension would be making use of background page. You could simply send message to background page inside beforeunload handler, catching all info you need to deal with, and execute the async call in background page. Sample code would be:
content.js
window.addEventListener('beforeunload', function() {
chrome.runtime.sendMessage({ info: "Here is the info you would like to pass to background page"});
});
background.js
chrome.runtime.onMessage.addListener(function(request) {
// The following is your async call
logout();
// Don't forget the following code
return true;
});
Don't forget to return true from the event listener in background page, since chrome.runtime.onMessage.addListener would become invalid when the event listener returns, see this answer for more details.
Try using async/await for your handler, that is:
$(window).on('beforeunload', async function(event) {
await logout();
event.preventDefault();
event.returnValue = false; // Seems require this for Chrome
});
Of course, you should have Promise returned from logout();
But I'm not sure if this is reliable.
Not really a clean solution but you can try setTimeout to force the code to wait while the logout is in progress.
var timeToLogoutInMs = 500;
setTimeout(function() {
// Nothing
}, timeToLogoutInMs);
EDIT: Why do you need to do this on the beforeunload hook? Why not set a manual option user to log out?
I have a form with one tricky field that needs to pass validation on the server side. So i need to capture for submit, send ajax request with this field, get result, if result is valid the continue form submission, other wise stop submission and show message.
How would i do that?
I got lost a little bit in "big picture" with events and callbacks.
Here is what i have so far.
$("form").submit(function( event ) {
event.preventDefault();
return check();
});
function check() {
var field = $('#myFiled').val();
if (!field ) {
show.error('Please enter VIN number and try again.');
return false;
}
$.getJSON('MyURL', function(data){
if (!data.valid) show.error('Invalid entry! Please try again.');
})
}
UPDATE
Please read the question.
In case of successful validation i need to continue regular form submission. Not via AJAX.
$("form").submit(function( event ) {
event.preventDefault();
checkAndSubmit();
});
function checkAndSubmit() {
var field = $('#myFiled').val();
if (!field ) {
show.error('Please enter VIN number and try again.');
}
else {
$.getJSON('MyURL', function(data){
if (!data.valid) {
show.error('Invalid entry! Please try again.');
}
else {
$.post('yourFromPostURL', $('form').serialize(), function(data){
//show something of success or failure.
});
}
})
}
}
Judging by your check() function, you already understand basic JavaScript validation. If you want a form's validation to fail, have its .submit() method return false, otherwise return true.
Just treat the data returned by the AJAX request the same way you did the field variable.
Perhaps the one thing your missing is how to make check() return false from inside the getJSON function. The answer to that is a simple matter of variable scope.
var data;
$.getJSON('MyURL', function(data_){
data = data_;
});
if (!data.result) return false;
Since JavaScript has function scope, data will still be accessible inside of .getJSON().
There is one more thing though, .getJSON() is an asynchronous AJAX request, meaning your validation function will finish without waiting for the result of the request. You want to use a syncrhonous ajax request so your check() function won't finish until your validation is done. However there is no way to make .getJSON() synchronous so you will have to use the .ajax() method. See this post.
EDIT:
Your issue is if there are no validation errors, you do not return a value. You must return true;.
The alternative to the AJAX form submit is to prevent form submission and execute validation at the button level.
$('#submitButtonID').click(function (e) {
e.preventDefault();
//start your AJAX validation
checkAndSubmit();
}
Then validate and upon success, you can still submit the form regularly.
function checkAndSubmit() {
var field = $('#myField').val();
if (!field ) {
show.error('Please enter VIN number and try again.');
}
else {
$.getJSON('MyURL', function(data){
if (!data.valid) {
show.error('Invalid entry! Please try again.');
}
else {
$('form').submit();
}
});
}
}
Server side validations will run upon post, but you won't interrupt the form submission with your AJAX validation because it's only captured at the button level. (If you need to capture the Enter button, see this answer: Capturing Enter button to submit form
$('form[name=addform]').submit(function() {
if(error == true){
return false;
}else{
$('#loading').empty();
$('#loading').append("<img src = './images/ajax-loader.gif'/>");
$('#loading').show();
setTimeout(function(){
return true;
}, 4000);
}
error = false;
});
i need to load gif image before executes the return true. i do not use ajax for this please help
I'm not exactly sure what you are trying to accomplish, but that code won't work. setTimeout() does not pause the function it has been called from, nor does the return statement in the callback affect it.
JavaScript is asynchronous, not synchronous - setTimeout will not 'block' the execution of the next line of code. (See related What is the difference between synchronous and asynchronous programming (in node.js))
To submit the form after a delay (for what purpose is unclear) you will first need to stop the form submitting (by cancelling the event) then submit the form once again as when setTimeout callback is executed.
$('form').on('submit', function(event) {
// Prevent the form from submitting
event.preventDefault();
// 'this' is referring to the event target
var form = this;
// It may not be required to wrap the `form.submit` method but it's usually safer to do so
setTimeout(function() {
form.submit()
}, 4000);
});
Here is an example http://jsfiddle.net/xppNp/1/
I want to do some stuff when user is leaving a page, I add this code
window.onbeforunload = function (e){
return "You save some unsaved data, Do you want to leave?";
}
This prompt can notify the user and user can stay on the page or leave. But I want more to know whether he leaves or not, and do thing on his decision. I tried this,
window.onbeforunload = function (e){
var event = jQuery.Event(e);
var result = confirm('want to leave?');
if (result == false){
//do sth..
event.preventDefault();
}else{
//do clean up
}
}
But it fails!! It always goes away!
Can any body help me doing this?
The method you use (preventing bubbling of the event) is intentionally not possible, otherwise you could prevent users from leaving your page.
You can achieve something similar to what you want by doing your cleanup onunload, and do the stuff you always want to do onbeforeunload.
But I want more to know whether he leaves or not, and do thing on his decision
If you wanna do something when he leaves, you can do it in unload event. For example, as #Erik Bakker mentioned you can send async events in unload event.
However if you wanna find out if user "stayed", in other words cancelled the leaving process, there is a way as well. It's kinda hackish, but it works.
const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
alert('user stayed!!!');
}
window.addEventListener('beforeunload', function onBeforeUnload(e) {
setTimeout(doSomethingWhenUserStays, 500);
// Dialog text doesn't really work in Chrome.
const dialogText = 'A dialog text when leaving the page';
e.returnValue = dialogText;
return dialogText;
});
Method doSomethingWhenUserStays will be called every time, but if user leaves the page, he won't see what it performed anyway. It can perform asynchronous stuff, synchronous, it doesn't really matter because it's within setTimeout therefore it's out of the normal flow of onBeforeUnload and won't interfere with it.
If you want to perform it ONLY if user really stays on the page it's slightly harder. You'd have to set a global flag that checks whether user reached unload or not and only then call what's inside doSomethingWhenUserStays. Consider the following example.
let hasUserLeft = false;
const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
// Perform the following only if user hasn't left the page
if (!hasUserLeft) {
alert('user stayed!!!');
}
}
window.addEventListener('beforeunload', function onBeforeUnload(e) {
// It won't perform doSomethingWhenUserStays in 500ms right after this is called,
// but instead, it will perform it in 500ms after you click "Stay" or "Leave".
// Therefore, there should be some time for `unload` handler to fire and
// set `hasUserLeft` flag before `doSomethingWhenUserStays` is called.
setTimeout(doSomethingWhenUserStays, 500);
// Dialog text doesn't really work in Chrome.
const dialogText = 'A dialog text when leaving the page';
e.returnValue = dialogText;
return dialogText;
});
window.addEventListener('unload', function onUnload() {
hasUserLeft = true;
});
As far as I have read about this method in different browser forums like MSDN, MozillaDev, etc, this method does not have any callbacks for OK/Cancel. You have this for the confirm dialog but not for this.
This is a security implementation to allow users to have full right about which website they should see. Also, it averts hackers from locking users to their sites.