'onbeforeunload' Fires Twice - javascript

I want to send an ajax request when a user leaves a page or closes the window.
Here is my code inside :
<script type="text/javascript">
function sendajax(){
$.ajax({
url: "someurl",
data: mydata,
async : false
});
}
</script>
<script type="text/javascript">
window.onbeforeunload=function(){sendajax();};
</script>
When the event occurs the event fires twice.
Why does in happen?
I know I can prevent it by adding a variable var ajaxSent=true; but may be there is a cleaner way to do it?
UPD:
I replaced the sendajax function content with some other code (without sending ajax) and found out that ajax is not the one causing the problem. It still enters the function twice.

Based on the code in your edit and comments, it looks like it could simply be caused by the broken link you are clicking to leave the page.
Given the following code:
<script>
function doSomething() { console.log('onbeforeunload fired'); }
window.onbeforeunload = doSomething;
</script>
link A
link B
If I click on link A, I get two console log entries, if I click on link B I only get one.
It looks like it could be a quirk of how the browsers handle their internal "This web page has not been found" pages, causing your page to be refreshed and closed again before showing the message, leaving you with two occurrences of the onbeforeunload event.

I had the same problem and it took a while to understand and resolve, sharing the case details:
There was a custom JS within our template that manipulated the menu.
It caused the unload to fire twice, only when clicking on the menu links, not on other links, and only in IE/EDGE.
We eventually stopped the propagation on these links and the problem was resolved.
$('.SELECTOR a[href^="http://"]').on('click', function(e){
e.stopPropagation();
});
It's a specific bug in your application, therefore you won't find too much information on google.

You could try the following code:
<script type="text/javascript"><br>
window.onbeforeunload=function sendajax(){<br>
$.ajax({<br>
url: "someurl",<br>
data: mydata,<br>
async : false<br>
});<br>
};<br>
</script>
or you can define sendajax() {} at some place and the use it like onbeforeunload = "sendajax()" not as onbeforeunload = "function () { sendajax() }"

beforeUnload is cancellable
I know this post is quite old but from the Chrome Pagelifecycle API documentation, browsers can occasionally partially unload pages to save resources. https://developers.google.com/web/updates/2018/07/page-lifecycle-api beforeUnload is not reliable to make sure that the page is closed. This especially happens on android devices when the screen is locked.
There is a jsfiddle that I found somebody wrote that you can test out https://jsfiddle.net/ov6b9pdL/. Keep the screen locked for 5-10 minutes on Chrome android and you'll see that beforeUnload is fired without even closing the tab.
$(document).ready(function() {
window.addEventListener('beforeunload', showLoader);
});
var showLoader = function() {
$('#loader').show();
};

Agree with AlonMichaeli's concept.
In my application there was anchor tag wrapped with in a div together with couple of spans. When Anchor was clicked on a dirty page, there was couple of 'Leave site' notifications.
It worked fine if any other part of menuItem (div or spans) are clicked.
So in custom javascript method I've added stopped propagation and preventDefault only if anchor tag is clicked. Somehow in this case preventDefault is necessary.
function menuItemClicked(event: JQueryEventObject) {
var item = $(event.target);
if (item.is(".anchor-item")) {
event.stopPropagation();
event.preventDefault();
}
href = item.closest(".anchor-item").attr("href");
if (!event.ctrlKey && href) {
window.location.href = href;
}
}

Related

Click event triggered from parent page not working in IE

I am working with a filter on page to display different products. I am trying to make it so that when you click a button from an external page, it navigates to the product page and automatically clicks the "organics filter" checkbox and then displays the organic items. This code works in every browser except IE and EDGE. Any ideas what could be wrong? It appears to click the organics checkbox but it does not actually click the submit button for IE and EDGE.
**Update: It works if I put an alert after the window.load function. I think its a timing issue or something. Anyone have any suggestions?
//force organic filter if coming from organics article
$(window).load(function(){
var organicURL = document.referrer;
if (organicURL === "http://www.sampleurl.com") {
$('#organicFilter').trigger('click');
if ($('#organicFilter').is(':checked')) {
$('#submitFilter').trigger('click');
}
}
});
In order to trigger click event, you should use the jQuery .click() function. Also, have a look here : jQuery.trigger('click') not working
and here :
Trigger click event not working in IE10
I fixed it by adding this below:
$(window).load(function(){
var organicURL = document.referrer;
if (organicURL === "http://www.centowine.com/articles/2017/cento_organics.php") {
$('#organicFilter').trigger('click');
if ($('#organicFilter').is(':checked')) {
setTimeout(function(){ $('#submitFilter').click()}, 500);
}
}
});
Just needed to add a timeout it was loading too soon. Before the document loaded.

on click event inside pageinit only works after page refresh

I know there're a lot of duplicate questions out there, I checked almost all of them, but I just couldn't find a solution in my case. So, here's my problem:
I have a banner which will show on every page of the project, inside the banner there's a close button to close the banner, and a download button which leads user to the app store to download the app. My banner works perfect only except I have to refresh the page to get these two buttons works. Here's my code:
$(document).on("pageinit", function () {
$("#close").on("click", CloseBanner);
$("#download").on("click", SetAppStorePath);
//alert("pageinit");
});
function SetAppStorePath() {
if (isIOS) {
window.location = "https://itunes.apple.com/us/app/myapp/id.....";
}
else if (isAndroid) {
window.location = "https://play.google.com/store/apps/details?id=.....";
}
}
function CloseBanner() {
$('.banner').hide();
}
Here's the simplified html:
<div class="banner">
<div class="container">
<a id="close">×</a>
<a id="download">Download</a>
</div>
</div>
I did a little test, and found something tricky: I added that alert inside pageinit, I noticed that the alert is always executed(means my button on click events are always registered) when I jump from page A to page B. But when the button works, I see page A is gone, blank page shows, alert shows, then page B shows, the buttons work. When it doesn't work, the order is different, I still can see page A, then I see alert(I still can see page A now), then it changes to page B, the buttons don't work.
So seems that when pageinit executed after page jumped, it works,but sometimes pageinit executed before page jumped, then it doesn't work.
I think your elements are dynamically created. You may need event delegation.
$(document).on("pagecreate", function () {
$("body").on("click", "#close", CloseBanner);
$("body").on("click", "#download", SetAppStorePath);
});
Move following outside of the init and change it like following
$(document).on("click","#close", CloseBanner);
$(document).on("click","#download", SetAppStorePath);
when page init executes, DOM is not ready. that is the reason it is not binding to close or download elements. and this is the way to overcome that. you dont need pageinit event here

Prevent back button from going back to previous page for an ID

Using the following function to prevent users from going back to previous page if the page they are on currently has the id #home. But this function doesn't even fire off. No alerts. Nothing wrong with the link to script file as I have other scripts running fine on that file.
document.addEventListener("backbutton", function (e) {
alert("Back button pressed");
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
var activePageId = activePage[0].id;
alert(activePageId);
if (activePageId == 'home') {
e.preventDefault();
}
}, false);
Unless you have created a custom event there is no onbackbutton event I know of. You are after onbeforeunload
Clients don't like it when you block navigation. You should consider other solutions to you problem rather than block navigation. Sure as .... the next thing the client will do is close the tab and a good chance you will never see a session with that client again.

Middle Click JS Function

I have a button on the site I am working on that uses a sprite sheet animation and so needs to be set as a background image. I require a regular click on the button to delay the redirect to another page by a fraction of a second for the animation to play, however I still wish for middle mouse clicks to function to open in new tab, without a delay.
Currently I have this working in Javascript but it seems a pretty bad idea for everything to be handled that way and not to just have a href.
So I have made this:
<script type="text/javascript">
function delayed(){
window.stop();
setTimeout('window.location = "http://www.dog.com";', 800);}
</script>
I am a link
The idea being that a regular click triggers the function and incurs a delay whereas a middle mouse click will just go straight to the href link.
This works in Firefox. However in Chrome and Safari the middle click triggers the function and as a result opens the dog link in the same window (on the finished version the links will be the same of course).
Basically all I need is a href that delays on click but still functions normally on middle click. My working solution uses Javascript to open in new tab on middle click but it strikes me that this may override browser settings and is probably a bad idea.
EDIT:
In the meantime I had found this solution using Jquery:
$(document).ready(function() {
$(".delayed").click(function() {
var href = $(this).attr('href');
setTimeout(function() {window.location = href}, 800);
return false;
});
});
...and the HTML:
<a href="http://www.google.com/" class='delayed'></a>
This worked but encountered the same problem with Chrome treating a middle click as a left click and hence opening it in the same window.
I have now modified it to include the content from sransara so that... I think... everything is resolved. Again using Jquery:
$(document).ready(function() {
$(".delayed").click(function(event) {
var href = $(this).attr('href');
if(event.button == 0){
event.preventDefault ? event.preventDefault():event.returnValue = false;
setTimeout(function() {window.location = href}, 800);
}
});
});
Seems to work in all browsers. Hopefully these can be of use to anyone stumbling upon this page in the future.
This is just a quick solution, but I think it mostly fits into your need.
The code of HTML anchor tag:
I am a link
Here is the Javascript:
function delayed(event){
window.stop();
if(event.button == 0){
event.preventDefault ? event.preventDefault():event.returnValue = false;
setTimeout(function(){ window.location = "http://www.yahoo.com"; }, 800);
}
}
There are few simple changes:
I have removed the return false from onclick event, but the new code line event.preventDefault ? event.preventDefault():event.returnValue = false;, prevents default action when left clicked.
And added a button code check to Javascript.
Working demo code is here.
This is a quick solution, some area for improvement is to:
Take out the inline onclick event and add an event listener dynamically with JS.

Ajax not working with Href (solution)

I was having many problems trying to find the reason of why my ajax function was not working on Safari, Chrome and sometimes Firefox, but worked very well on IE. I made a little change, and everything start working perfect (in every browser), but I still dont know why, and I want to find out the main reason of this.
I had an Ajax function respuestas() which insert some data on a database. This function is called by some links like this: <a onclick="respuestas()" href="link.html">LINk </a>. So when I click on the link, the function takes the proper information and inserts it on the database and then go to link.html. Again, this only worked for IE.
I insert an alert(xml.responseText) to see the response that i was having. Safari, fireforx and chrome returns an empty alert.
I was tired of changing pages everytime I wanted to test my function, so I add a button calling my function (without going to another webpage) and IT WORKED!. Now, I have something like this: <a onclick="respuestas()" href="#">LINK </a> and put window.location.href="link.html" inside my ajax function, so the change of pages occur after the ajax response is completed, and it is working very well.
But I do not entirely understand why this works and the other way does not.
This because the link element has also it's default listener. So, to prevent any extra action on click, you should prevent default action. The simple way to do this is to return false on click.
<a onclick="respuestas(this); return false;" href="link.html">LINk</a>
And your respuestas in easiest way should be like this:
function respuestas(link) {
/* do what you need here */
window.location.href = link.href;
}
This is pretty primitive, but I believe you'll get the idea.
What's happening here is that your browser was navigating to the next page before repusetas() was able to execute. In order to ensure that your script is going to fire before the browser follows the link, you need to take control of the click event. In jQuery it works like this:
$('a').bind( 'click', function( event ){
event.preventDefault();
repuestas();
var href = $(this).attr('href');
window.location.href = href;
});
Try this Jquery code
function respuestas()
{
$.ajax({
type: "post",
url: "insert.php?data="+data,
success : function(data){
window.location.href="link.html";
},
error : function(){
alert("Could not ");
}
});
}

Categories

Resources