I want to execute some code before the window closes but i don't want to display the prompt.
Here is my code :
$window.onbeforeunload = function(){
$rootScope.$broadcast('war-change');
return undefined;
};
$scope.$on('war-change',function(){
console.log('here');
//Execute some more code here.
});
returning undefined or false is not working as my code is not getting executed.
any help is appreciated.
You code does work as intended. Check the following fiddle:
https://jsfiddle.net/8ubz4bxg/
<div ng-app>
<h2>Test unload</h2>
<div ng-controller="unloadCtrl">
</div>
</div>
And controller same as you have:
function unloadCtrl($scope,$window,$rootScope) {
$window.onbeforeunload = function(){
$rootScope.$broadcast('war-change');
return undefined;
};
$scope.$on('war-change',function(){
console.log('here');
//Execute some more code here.
});
}
But, there are limitations on what you can do with the beforeunload method, because once unload is committed, you have a very limited time to do something. To test how much time you have, you can use the following modification:
$scope.$on('war-change',function(){
console.log('here');
//Execute some more code here.
setTimeout(function(){ console.log("ha-ha")}, 100)
console.log("he-he")
});
Now, if you decrease the timeout to something like 0-100, you may still see "ha-ha" int he output. Increase it to 2 seconds (2000) and most probably you will not see that line.
Related
I'm trying to get a javascript function to run only once. I've seen this question has been asked before, e.g. Function in javascript that can be called only once, but I can't get the solutions in here to work. I'm not sure if it's because I've got nested functions, or whether there's something I'm missing. Essentially, I'm trying to run a function which, when a webpage is scrolled, it:
- runs a little animation on a canvas in the header
- reduces the size of the header
- leaves it at that
But when there is any subsequent scrolling, the animation keeps re-running. Here's a summarised version of the non-working code:
$(document).on("scroll",function(){
var arrange_title = function(){
//some code
};
if($(document).scrollTop()>0){
arrange_title();
arrange_title = function(){};
setTimeout(function(){
$("header").removeClass("large").addClass("small");
},1000);
}
});
I've also tried declaring a global variable, setting it to "false" in a "window.onload" function, then set it to true in an if function that runs the animation (the if function running only if the variable is false), but that doesn't stop it either. Thoughts?
What you're looking for is something along the lines of listenToOnce where the listener fires the one time, but never again. This could be modified to a number of calls, but the logic is like so:
Register the listener.
Then once the listener fires, remove it.
See .off
$(document).on("scroll",function(){
var arrange_title = function(){
//some code
};
if($(document).scrollTop()>0){
arrange_title();
arrange_title = function(){};
setTimeout(function(){
$("header").removeClass("large").addClass("small");
// $(document).off('scroll'); // or here
},1000);
}
$(document).off('scroll'); // remove listener, you can place this in the setTimeout if you wish to make sure that the classes are added/removed
});
Don't use a time out. That is why you are getting in trouble. Declare a variable outside of your function using var, that will make it global. Your code should be inside of a check for that variable. Before executing your code the first time but inside of the check, change that variable so that the code will never run again.
Try avoid setTimeout. Almost all animation can be watched for end.
function doHeaderAnimation() {
return $('header').animate();
}
function makeHeaderSmall() {
$("header").removeClass("large").addClass("small");
}
function handleScroll(event) {
if ($(document).scrollTop() > 0) {
doHeaderAnimation().then(makeHeaderSmall);
$(document).off("scroll", handleScroll);
}
}
$(document).on("scroll", handleScroll);
basically I want to run some code in jquery after the user has stopped doing anything in the browser like click,scroll. How to know if all functions have finished and jquery is not being busy (being run or used)
Basically run code only when the user is idle
If I am getting you right, this is what you were looking for
<script>
$(function(){
(function(seconds) {
var refresh,
intvrefresh = function() {
clearInterval(refresh);
refresh = setTimeout(function() {
alert('No activity from user 10 seconds, put your code here !');
}, seconds * 1000);
};
$(document).on('click keydown keyup mousemove', function() { intvrefresh() });
intvrefresh();
}(10));
});
</script>
Typically you'd wait until everything has loaded. This means that all elements have finished loading on the page (e.g. Images loaded in). There's nothing here to tell you that there's no JavaScript running in the background though.
$(window).load(function() {
// Do stuff
});
try {
var str =$('body').html();
} catch ( e ) {
alert('jquery not used');
}
Do something like this. jsfiddle
I just answered it here. See if it makes sense.
TLDR;
You can do it more elegantly with underscore and jquery-
$('body').on("click mousemove keyup", _.debounce(function(){
// your code here.
}, 1200000)) // 20 minutes debounce
I need to test if specific methods are called when user scrolls the window to a certain point. In my source code I have windows listener attached, something like:
$(window).on("scroll.singleJob",function(e)
{
// code here, check if the window is scrolled past certain point etc. and then I need to call this method
LozengesPanel.makeFixed();
}
Now, in my Jasmine test I'm trying to confirm that the method is being called when the window is scrolled to a certain point. So I set up the test:
describe("SingleJob page", function() {
beforeEach(function() {
loadFixtures('my_fixture.html');
});
it("panel sticks to top when page scrolled down", function() {
spyOn(mycompany.singleJobTestable.LozengesPanel, "makeFixed");
window.scroll(0,1000);
expect(mycompany.singleJobTestable.LozengesPanel.makeFixed).toHaveBeenCalled();
});
});
But the test fails, all I get is Expected spy makeFixed to have been called.
How can I trigger window scroll so I can test methods inside of this callback?
EDIT:
Finally it all makes sense.. It seems that scroll event was put in a tasks queue only to be executed after the current thread finishes. Adding $(window).trigger("scroll"); did the trick. I posted short blog post about it that explains the issue http://spirytoos.blogspot.com.au/2014/02/testing-windowscroll-with-qunitjasmine.html
EDIT: This answer does not satisfy the question. See the comments for the reason.
Actually, it looks like you are triggering the scroll event from your Jasmine spec. I tried very similar code, which I include below. However, my expect still fails, like yours (I'm still getting familiar with Jasmine, so I can't explain with certainty why that is).
var fun = {
scrollEventCallback: function() {
console.log('scroll event triggered');
}
};
$(window).on('scroll', fun.scrollEventCallback);
describe("A test suite", function() {
it("should trigger f", function() {
spyOn(fun, "scrollEventCallback");
$(window).trigger('scroll'); // my callback function is executed because it logs to the console
expect(fun.scrollEventCallback).toHaveBeenCalled(); // this fails anyway
});
});
Maybe your window.scroll(0, 1000) is not actually pushing the viewport low enough to trigger your Lozenges.makeFixed() call. That would be the case if the page (your fixture, I think) wasn't long and it didn't actually have anywhere to scroll.
Also, I got code similar to your provided code to work. The expect(...) succeeds. It is pasted below.
var LozengesPanel = {
makeFixed: function() {
console.log('makeFixed was called with its original function definition');
}
};
$(window).on("scroll.singleJob",function(e) {
LozengesPanel.makeFixed();
});
describe("A test suite", function() {
it("should trigger callback", function() {
spyOn(LozengesPanel, "makeFixed");
$(window).trigger('scroll'); // nothing is logged to the console
expect(LozengesPanel.makeFixed).toHaveBeenCalled(); // succeeds
});
});
I'm using javascript setInterval function to make some queries to a server but when the unload method is trigged the GETs are not stopping.
$(document).ready(function(){
example.init();
});
$(window).unload(function(){
clearInterval(example.INTERVAL_ID_1);
alert(example.INTERVAL_ID_1+" killed!");
});
var example= {
init: function(){
this.INTERVAL_ID_1;
...
this.INTERVAL_ID_1 = setInterval(function(){
...
}, 9000);
},
...
}
The unload method is called, the alert gives the right INTERVAL_ID but it stays alive, I can see the queries being made in the server console.
Somehow it's working... it's strange sometimes the server console is flooded with GET and POST, but now it's working... strange.
Thanks though ;)
I have this script on a page of mine and the setTimeout function never fires. It's just an alert right now but i'm just testing it out. I'm doing a meta refresh on the page just after it if that's any clue, but i've also given that a 10 sec delay so the page isn't refreshed before it's supposed to trigger.
Also, the related question: If I run a javascript with a delay of, say, 10 seconds (with setTimeout) and in that javascript I try to modify a design element that's not on the page when the setTimeout is declared but will be by the time the script is fired. Will it work?
<script language=javascript>
var xmlhttp_get_memento;
function loop_alerte(){
setTimeout( function() {
alert("timeout");
}, 5000);
xmlhttp_get_memento = new XMLHttpRequest();
if (xmlhttp_get_memento==null)
{
alert ("Browser does not support HTTP Request (1)");
return;
}
var url="crm/ajax/get_mementos.php";
url=url+"?sid="+Math.random();
xmlhttp_get_memento.onreadystatechange=function() {
if (xmlhttp_get_memento.readyState == 4) {
alert(xmlhttp_get_memento.responseText);
schimbare_tip_cursor("default");
}
else{
schimbare_tip_cursor("progress");
}
};
xmlhttp_get_memento.open("GET",url,true);
xmlhttp_get_memento.send(null);
}
loop_alerte();
</script>';
Your setTimeout looks good, so there's probably something else that's wrong. Have you tried using a javascript debugger to see if you get any errors?
As for your second question, yes, that shouldn't be any problem, as the anonymous function inside the setTimout won't be evaluated until it runs. Live sample here: http://jsbin.com/afonup/2/edit Both with and without jQuery.
There is nothing wrong with your setTimeout, you will need to debug further
As for your second question -- the function will run, but whatever it is you were trying to do will not work.
Cleaning up your code would be a nice start. I can imagine a browser doesn't understand the tag <script language=javascript>. I suggest to use <script type="text/javascript"> and if you're lucky, your javascript might work!