I am using following code to trigger the are you sure leaving website alert but for some reason its not recognising my if else condition in it and only works if I only put return true in window.onbeforeunload = function() { return true } . Is there a way I can trigger this alert only when user is navigating away from my website cause at the moment without if else condition its asking if user tries to navigate in the same website as well?
window.onbeforeunload = function() {
var location = window.document.activeElement.href;
if (typeof location != 'undefined')
{
console.log(location);
} else { reutn true; }
};
You can set a flag and toggle that flagged based on host of links that are clicked
var host = location.hostname,
allowNavigate = false;
window.onbeforeunload = function() {
if (!allowNavigate) {
return 'Message string';// not what actually gets displayed in most browsers these days
}
//don't return anything
return;
};
window.onload = function() {
document.querySelectorAll('a').forEach(function(a) {
a.addEventListener('click', function(e) {
allowNavigate = this.hostname === host;
});
});
};
The hostname on this page for example is "stackoverflow.com"
DEMO
You can add the "window.onbeforeunload" dynamically for the links you want to see the prompt message
and remove the "window.onbeforeunload" for the links you don't want prompt
<a onClick="a(true)" href="https://www.w3schools.com">Click here to get promt before navigate</a>
<br>
<a onClick="a(false)" href="https://jsfiddle.net/">Click here to navigate without promt </a>
<script>
function a(showPrompt){
window.onbeforeunload = showPrompt ? function(e) {return '';}: null;
}
</script>
https://jsfiddle.net/vqsnmamy/1/
Related
My home page has a couple of links: one for English version and the other for French version. Something like this:
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
I want to use JavaScript to remember the last choice made by visitors and when they come again, they don't have to choose the language one more time because I want them to be autoredirected to the preferred language using cookies.
P.S. the visitors are strangers, not registered users. I want to store cookies in visitors' browsers, not in the database. Please, help me by providing me with the full solution.
Gelerally, the idea is: set handlers on links and upon clicking save preferred version into localStorage. Then every time user loads any page of your site, just check, whether the url contains the language context ("en"/"fr") the user chose before. If yes - do nothing, user opened the right version; if not - redirect him to the previously saved version. The following is a Vanilla approach (not properly tested). You will have to tweak it (attachEvent etc.) or use jQuery library to implement similar ideas in a shorter and more cross-browser way.
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
JS:
function LanguageManager(selector) {
this.langLinks = document.querySelectorAll(selector);
}
LanguageManager.prototype.setHandler = function() {
var self = this;
this.langLinks.forEach(function(langLink) {
langLink.addEventListener("click", self.handler, false);
});
}
LanguageManager.prototype.redirect = function() {
var link = storageManager.restoreDataFromStorage();
if(link && !~window.location.href.indexOf(link)) window.location.href = link;
}
LanguageManager.prototype.handler = function() {
var e = event || window. event;
var elem = e.target || e.srcElement;
if(e.preventDefault) e.preventDefault(); else e.returnValue = false;
storageManager.saveDataToStorage(elem.href);
location.href = elem.href;
}
function StorageManager() {
this.storageName = "languageVersion";
this.storageData = null;
}
StorageManager.prototype.isStorageAvailable = function(type) {
try {
var storage = window[type], x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch(e) { return false; }
}
StorageManager.prototype.saveDataToStorage = function(data) {
if(!this.isStorageAvailable('localStorage')) {
this.storageData = data;
return false;
}
try {
localStorage.setItem(this.storageName, JSON.stringify(data));
return this.storageName;
} catch(e) {
this.storageData = data;
return false;
}
}
StorageManager.prototype.restoreDataFromStorage = function() {
if(this.storageData) return this.storageData;
return JSON.parse(localStorage.getItem(this.storageName));
}
var storageManager = new StorageManager();
var languageManager = new LanguageManager(".ensite");
languageManager.setHandler();
languageManager.redirect();
Also notice, that there may be issues depending on how you implement language contexts on your site. You can start with my code on your own and tweak it or find someone else to get this properly done.
Just tested this, it works perfect.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<a class="ensite" href="" onclick ="localStorage.setItem('language','en')">English</a>
<a class="ensite" href="" onclick = "localStorage.setItem('language','fr')">French</a>
<script>
$(document).ready(function(){
var language = (localStorage.getItem('language') == null)? 'en' : localStorage.getItem('language');
console.log(language);
})
</script>
I tried to override window.onbeforeunload to avoid double submitting while redirecting pages.
window.onbeforeunload = disableCurrentWindow;
function disableCurrentWindow()
{
console.log("Before Disable the contents");
window.document.body.disabled = true;
console.log("After Disable the contents");
return undefined;
}
If I return true here it will give default confirmation pop up which I don't need at the moment. I just need to redirect users to next page. But no need to allow double click
If you want to disable double submit GET requests you can try to update href param in each link for short period of time right after click.
For example,
var clickedAt = null;
$(document).ready(function() {
$('a').click(function() {
if (!clickedAt) {
console.log('click allowed, destination: ' + $(this).attr('href'));
clickedAt = new Date();
$('a').each(function() {
$(this).attr('data-href', $(this).attr('href'));
$(this).attr('href', '#');
});
}
else {
console.log('click masquaraded, destination: ' + $(this).attr('href'));
}
return false;
});
});
setInterval(function() {
if (typeof $ == 'undefined') return false;
if (clickedAt && new Date().getTime() - clickedAt.getTime() > 1000) {
$('a').each(function() {
$(this).attr('href', $(this).attr('data-href'));
});
clickedAt = null;
}
}, 100);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
data value
But I don't think - that you should do this. Double clicking is not a problem in most cases - it's not a DDOS for your web-server (if you see, that double clicks make a lot of load for your web-server - you should reconfigure it, because on production mode, load in any case will be more powerful).
BTW I have used data-href for dumping old href. If you are using those attributes - you can choose another one buffer.
P.S. If your page has a lot of links it can do some very small lags for your customers
Rewriting the question -
I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com
I made a program as follows -
var stayonthis = true;
var a;
function load() {
window.onbeforeunload = function(e) {
if(stayonthis){
a = setTimeout('window.location.href="http://google.com";',100);
stayonthis = false;
return "Do you really want to leave now?";
}
else {
clearTimeout(a);
}
};
window.onunload = function(e) {
clearTimeout(a);
};
}
window.onload = load;
but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(
Help Me !! Thanks in Advance
here is the fiddle code
here how you can test because onbeforeunload does not work on iframe well
This solution works in all cases, using back browser button, setting new url in address bar or use links.
What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler.
In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)
http://jsfiddle.net/W3vUB/4/show
http://jsfiddle.net/W3vUB/4/
EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!)
BTW, using bing.com due to google not allowing no more content being displayed inside iframe.
http://codepen.io/anon/pen/dYKKbZ
var a, b = false,
c = "http://bing.com";
function triggerEvent(el, type) {
if ((el[type] || false) && typeof el[type] == 'function') {
el[type](el);
}
}
$(function () {
$('a:not([href^=#])').on('click', function (e) {
e.preventDefault();
if (confirm("Do you really want to leave now?")) c = this.href;
triggerEvent(window, 'onbeforeunload');
});
});
window.onbeforeunload = function (e) {
if (b) return;
a = setTimeout(function () {
b = true;
window.location.href = c;
c = "http://bing.com";
console.log(c);
}, 500);
return "Do you really want to leave now?";
}
window.onunload = function () {
clearTimeout(a);
}
It's better to Check it local.
Check out the comments and try this: LIVE DEMO
var linkClick=false;
document.onclick = function(e)
{
linkClick = true;
var elemntTagName = e.target.tagName;
if(elemntTagName=='A')
{
e.target.getAttribute("href");
if(!confirm('Are your sure you want to leave?'))
{
window.location.href = "http://google.com";
console.log("http://google.com");
}
else
{
window.location.href = e.target.getAttribute("href");
console.log(e.target.getAttribute("href"));
}
return false;
}
}
function OnBeforeUnLoad ()
{
return "Are you sure?";
linkClick=false;
window.location.href = "http://google.com";
console.log("http://google.com");
}
And change your html code to this:
<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
try it
</body>
After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.
jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN
var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;
var handler = function(e) {
timeout = setTimeout(function () {
console.log('location.assign');
location.assign(offerUrl);
/*
* This value makes or breaks it.
* You need enough time so the browser can make the connection to
* the clicked links href else it will still redirect to the offer url.
*/
}, 1400);
// important!
window.onbeforeunload = F;
console.info('handler');
return 'Do you wan\'t to leave now?';
};
window.onbeforeunload = handler;
Try the following, (adds a global function that checks the state all the time though).
var redirected=false;
$(window).bind('beforeunload', function(e){
if(redirected)
return;
var orgLoc=window.location.href;
$(window).bind('focus.unloadev',function(e){
if(redirected==true)
return;
$(window).unbind('focus.unloadev');
window.setTimeout(function(){
if(window.location.href!=orgLoc)
return;
console.log('redirect...');
window.location.replace('http://google.com');
},6000);
redirected=true;
});
console.log('before2');
return "okdoky2";
});
$(window).unload(function(e){console.log('unloading...');redirected=true;});
<script>
function endSession() {
// Browser or Broswer tab is closed
// Write code here
alert('Browser or Broswer tab closed');
}
</script>
<body onpagehide="endSession();">
I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...
Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)
Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.
My Code:
//hold window open on form change
window.onbeforeunload = function(e) {
if(formChanges > 0) {
if(formData != initFormData) {
if(confirm('here')) {
e.preventDefault();
}
else {
e = null;
}
}
else {
e = null;
}
}
else {
e = null;
}
};
The three vars (formChanges, formData, and initFormData) are all being filled correctly, and little tests have shown that they are being read correctly within the function. The problem is that the page unloads nomatter what, and no confirmation dialog ever appears.
The console log flashes for a moment before being unloaded (I can't seem to write it's contents to file) and I can see the message Blocked confirm 'here' during beforeunload, but it's gone before I can access it. Any help is appreciated!
WHen using onbeforeunload you have to return a string, like so:
window.onbeforeunload = function(e) {
return 'Dialog text here.';
};
source: https://developer.mozilla.org/en-US/docs/Web/API/Window.onbeforeunload
I open a popup with the click event of a hyperlink... The popup contains records from a server.
The problem is that when I click rapidly, there are multiple popups at once.
There is a way to prevent this? in which can open a single popup
My code:
$('.wrapper_form a.add').click(function(e)
{
e.preventDefault();
if(typeof(currentPopup) == 'undefined' || currentPopup.closed)
{
url = 'server_page.aspx';
currentPopup = window.open(url,'server','height=500,width=800');
if (window.focus) {currentPopup.focus()}
}
else
{
currentPopup.focus();
}
});
Here is one approach. Not the best solution but it should work. What this code will do is protect against clicking the link a bunch of times and have it open a new instance for each click. This code will not allow the window to be opened more than once in a 1/2 interval, of course you can change the timing.
var hopefullyThisIsNotInGlobalScope = false;
$('.wrapper_form a.add').click(function(e)
{
if (hopefullyThisIsNotInGlobalScope)
{
return false;
}
hopefullyThisIsNotInGlobalScope = true;
setTimeout(function () { hopefullyThisIsNotInGlobalScope = false; }, 500);
e.preventDefault();
if(typeof(currentPopup) == 'undefined' || currentPopup.closed)
{
url = 'server_page.aspx';
currentPopup = window.open(url,'server','height=500,width=800');
if (window.focus) {currentPopup.focus()}
}
else
{
currentPopup.focus();
}
});
Assuming the popup is on the same domain as the window launching it you might be able to replace hopefullyThisIsNotInGlobalScope variable with a global var attached to the window. You can then set that variable when the popup launches and alter it using the browser unload event