I want to combine two techniques in page transition. first, when user click a link , the click event should be delayed about 200ms and displaying css animation (ex: fading), after that the new page will be loaded normally. Then, for visitors with slow internet connection, they will be presented with pre-loader right after the first animation. The problem is, it seems both techniques doesn't fit each others. Any advice guys?
PS: Actually I inspired by these guys website : http://rsq.com/
here's my code:
$body = $("body");
$(document).on({
ajaxStart: function () {
$body.addClass("loading"); //for slow connection, visitors with faster connection may not notice this...
},
ajaxStop: function () {
$body.removeClass("loading");
}
});
$('a').on("click", function () {
if ($(this).attr('href') != '#') {
var href = $(this).attr('href');
$('#wrapper').addClass('fade_animation'); //animation right before new page request
setTimeout(function () {
window.location = href
}, 200);
return false;
$.post($(this).attr('href'));
}
});
I think this is enough:
Instead of:
return false;
$.post($(this).attr('href'));
do this
$.post($(this).attr('href'));
return false;
So the $.post gets executed.
I think i found a solution , but don't know if it's a good way, but it works.
$('a').on("click", function(){
if($(this).attr('href') != '#')
{
var href = $(this).attr('href');
$('#wrapper, footer').addClass('fading animation');
setTimeout(function() {
// window.location = href
$.post(window.location = href) // this line works :)
}, 200);
return false;
// $.post($(this).attr('href'));
}
});
Related
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..
}
});
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.
I have a function applied to setInterval function. When I minimize or change the focused window, then get back to the browser showing my web site, the browser plays everything that happened since i changed the focus to another window, in a very fast manner.
Is there a way to hold the animations, setintervals when window of focus in windows change ?
Thanks.
I found this post:
JavaScript / jQuery: Test if window has focus
for me it worked on google chrome but it could be that it doesn't work in some browsers.
Here is a fiddle to test:
http://jsfiddle.net/ScKbk/
His answer:
var window_focus;
$(window).focus(function() {
window_focus = true;
})
.blur(function() {
window_focus = false;
});
$(document).one('click',function() {
setInterval(function() { $('body').append('has focus? ' + window_focus + '<br>'); }, 1000);
});
Try this.
var handeler;
function ShowAnimation()
{
//SetInterval code
handeler = SetInterval(myfunction, 1000);
}
//clear the handler when not in use.
function Clearhandler()
{
ClearTimeout(handeler);
}
//call the above method on the onblur event of window.
$(window).focus(ShowAnimation(),Clearhandler());
Much like Getu.ch answer except this will only execute your "work" code if the window has focus (runs every 3 seconds). Not tested in all browsers but here is a link showing browser compatibility of window.focus / window.blur
(function($) {
var windowHasFocus = false;
$(window).focus(function() {
windowHasFocus = true;
});
$(window).blur(function () {
windowHasFocus = false;
});
setInterval(function() {
if(windowHasFocus) {
//Do your work
}
}, 3000);
});
I have a Tab widget set up on my website using JQuery 1.7.2 and JQuery UI 1.10.3.
I have written a JavaScript that parses the hash part of a URL in order that I can open a tab, load content into a div and scroll to a named anchor.
I can get the tab to open and content to load fine, however, scrolling to the anchor is proving to be a real pain.
I can get it to work if I trigger an alert before the scroll to the anchor (forcing you to click 'OK', but if I disable the alert (which I want to), it doesn't work.
I am guessing that it has something to do with waiting for the functions to finish processing first? But I'm quite inexperienced with JavaScript so would appreciate any help anyone could could give.
URL example: http://www.mysite.com/abc.html#tab=tab-3&#srv=includes/xyz&#anc=myanchor
My JavaScript is as follows:
$(document).ready(function () {
var parts = location.hash;
parts = parts.split('&'); // Hash parts of URL.
for (var i = 0; i < parts.length; i++) // Loop to separate variables.
{
if (parts[i].substr(1, 4).toUpperCase() == "TAB=") {
var tab = parts[i].substr(5).split("-").pop() - 1
} // Tab no. part from tab name.
if (parts[i].substr(1, 4).toUpperCase() == "SRV=") {
var srv = parts[i].substr(5)
} // Path to content to load.
if (parts[i].substr(1, 4).toUpperCase() == "ANC=") {
var anc = parts[i].substr(5)
} // Named anchor to locate.
};
// Tab found in URL so we'll check it exists and open it.
if (tab == -1) // Tab not found?
{
tab = 0 // Default to 1st tab if not.
};
$("#tabs").tabs("option", "active", tab); // Select the tab.
// Load content if provided in URL.
var href = $('.list li a').each(function () {
var href = $(this).attr('href');
if (srv == href.substr(0, href.length - 5)) {
var toLoad = srv + '.html .maint_content';
$('.maint_content').load(toLoad)
}
});
// Load content when selected from list.
$('.list li a').click(function () {
var toLoad = $(this).attr('href') + ' .maint_content';
$('.maint_content').fadeOut('normal', loadContent);
$('#load').remove();
$('.maint_content').fadeIn('normal', loadContent);
$('#load').fadeIn('normal');
window.location.hash = $(this).attr('href').substr(0, $(this).attr('href').length - 5);
function loadContent() {
$('.maint_content').load(toLoad, '', showNewContent());
}
function showNewContent() {
$('.maint_content').show('normal', hideLoader());
}
function hideLoader() {
$('#load').fadeOut('normal');
}
return false;
});
// Scroll to locate anchor.
//alert(anc);
$('html, body').animate({
'scrollTop': $('#' + anc).offset().top
}, 1000);
});
Thanks
I'm assuming the anchor you want to jump to is in the loaded content?
If so, just add a callback to the ajax call and do the jump there:
$('.maint_content').load(toLoad,'',showNewContent()).done(function () {
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
});
You are ajaxing the content of the div. This means it is loading asynchronously. The animate function is thus called before the loading of the content has finished, and the anchor you are looking for is not yet there.
In order to fire the animation when the loading is complete, you can pass a function to .load()
$('.maint_content').load(toLoad,'',showNewContent());
so you allready got that: showNewContent is fired when the loading finishes.
So all you have to do is move your animation line to the end of that function.
function showNewContent()
{
$('.maint_content').show('normal',hideLoader());
$('html, body').animate({'scrollTop': $('#'+anc).offset().top}, 1000);
}
My problem here is i want to avoid calling a javascript function for a time period(say after 5 sec) after it has been called.
i created a link, which calls the javascript function.and if the user double clicks it is called twice i want to avoid that.
Thanks,
Devan
I think the most sensible way to handle that is to disable the link once it is clicked, and then reenable it when the function is done running. Assuming you have jQuery available, something like...
$('#button').click(function () {
$(this).attr("disabled", "true");
doTheFunction();
$(this).attr("disabled", "false");
});
If you really need to wait a set amount of time after the function is called, then you could use setTimeout to reenable the button.
$('#button').click(function () {
$(this).attr("disabled", "true");
doTheFunction();
var btn = $(this);
setTimeout(function () {
btn.attr("disabled", "false");
}, 5000); // reenable the button 5 seconds later
});
EDIT: (for the comment below)
For a link, I would simulate the above by adding and removing a class, since you're right, there's no disabled attribute.
$('#link').click(function () {
if ($(this).hasClass('disabled_link')) {
return;
}
$(this).addClass("disabled_link");
doTheFunction();
var link = $(this);
setTimeout(function () {
link.removeClass("disabled_link");
}, 5000); // reenable the button 5 seconds later
});
Since you are using a link, not a button, and not jQuery (apparently), here's how to stop a function doing anything for 5 seconds (or whatever delay you want) after it has been called and done something:
var someFn = (function() {
var lastCalled;
return function() {
var now = new Date();
var limit = 5000; // minimum milliseconds between calls
if (!lastCalled || (now - lastCalled) > limit) {
lastCalled = now;
// do stuff
alert('hey');
} else {
return;
}
}
}());
This sort of thing is generally handled at the server though, since client scripts aren't particularly reliable - you can't guarantee that the dealy will be implemented, no matter what strategy you use.