I am new to javascript, and I am coding a game.
I would like to break out of the setInterval loop when a condition is met to display a game over screen. My code :
var timer = 0;
var i =0;
fond.onload= function()
{
timer = setInterval(boucle,50);
console.log("break");
}
function boucle()
{
i++;
if(i===4)
{
clearInterval(timer);
}
}
I never reach the break log because just after the clearInterval, the screen is stuck.
Thank you!
I am not sure what fond.onload represents in your code, but if you want the code to run when the page is loaded you should use window.onload or document.onload.
onload is a global event handler bound to all objects that gets executed when that object is loaded. I presume that in your case fond is never loaded as the rest of the code is fine, just never runs. It will run fine if you bind the function to window.onload.
You can read up more on that here
Related
I'm writing a "Game of Life" in javascript. I have all the logic done in a function called doGeneration(). I can repeatedly call this from the console and everything goes as planned, however, if I put it in a while loop the execution blocks the UI and I just see the end result (eventually).
while (existence) {
doGeneration();
}
If I add a setTimeout(), even with a generation limit of say 15, the browser actually crashes (Canary, Chrome).
while (existence) {
setTimeout(function() {
doGeneration();
},100);
}
How can I call doGeneration() once every second or so without blocking the DOM/UI?
You want setInterval
var intervalId = setInterval(function() {
doGeneration();
}, 1000);
// call this to stop it
clearInterval(intervalId);
I would use requestAnimationFrame(doGeneration). The idea of this function is to let the browser decide at what interval the game logic or animation is executed. This comes with potential benefits.
https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/
Rather than using setINterval or setTimeout and assume some random time interval will be enough for the UI to update you shoul/could make the doGeneration smart enough to call itself after dom was updated and if the condition of existence is satisfied.
I have this code:
window.setTimeout(function() {
let sudokuBodyWidth = $sudokuBody.outerWidth(true);
let sudokuBodyHeight = $sudokuBody.outerHeight(true);
console.log(sudokuBodyWidth + ',' + sudokuBodyHeight);
$sudoku.hide();
$welcomeOverlay.css({
width: sudokuBodyWidth,
height: sudokuBodyHeight
}).show();
}, 800);
window.clearTimeout();
I've put this code in a setTimeout because it takes a lot of time the DOM to load, so the JS code is to early with executing and returns 0 for the values (it's a huge codebase and I'm not 'allowed' to change the site structure to make the JS load later).
The problem is that this code runs twice. First, it returns the correct result, but then it returns 0 for both variables immediately after the correct values. As you can see, I've added a clearTimeout to prevent the execution to happen twice. But it keeps executing twice.
I've also tried:
let welcomeTimeout = setTimeout(function() {
// the code
});
clearTimeout(welcomeTimeout);
When doing this, the code doesn't execute at all.
window.clearTimeout() will do nothing because you are not passing the timerId witch get returned by window.setTimeout() and this should not run twice there is something else witch is causing this function to run twice
and in second one clearTimeout(welcomeTimeout); clears the timer that's why your code doesn't run
if you want to run your code after the document get loaded fully then you can use window.onload = function(){...}
or if you are using jQuery then you can also try $(document).ready(function(){...})
It should execute only once check Ur code base if u r loading script two times mean while put clearTimeout code at the end in the ananymous function given to setTimeout function
Putting the code at the end of HTML executes it when the DOM is loaded.
Use this:
<html>
<head>
<script async src="..."></script>
...
</head>
<body>
...
...
<script>(function() { init(); })();</script>
</body>
</html>
Function init() will fire when the DOM is ready.
Also you're using setTimeout() wrong, take a look at this example.
var what_to_do = function(){ do_stuff(); };
var when_to_do = 3000; // 3000ms is 3 seconds
var timer = setTimeout(what_to_do, when_to_do);
Alright, right now I'm writing a little JavaScript code that I can just simply copy paste into the Firefox Console and run. (I'm sorry, I'm still a massive noob, and I want to write a little script that basically, opens a certain web page and collects information form certain divs in it.)
However, I'm struggling at the moment. I would like to open a certain webpage, and then, after it is entirely loaded, execute a certain function. (for simplyfying reasons, this function just counts from 0 to 99.)
function openGroupsPage() {
window.location.replace(groupURL);
setTimeout(function() {
for (i = 0; i < 100; i++) {
console.log(i)
}
} , 10000)
}
openGroupsPage()
My problem is : The incrementing function never gets called (or atleast it seems like it because i can never see any kind of output in the console.) Why is my setTimeout not working or what is another option to accomplish what I would like to do? I would just really like to run a specific function when the newly accessed website is finished loading entirely.
When you change the location, the window object and all of its associated things (including timers) are discarded and a new one created. You can't schedule code to run in the new document from within the old document (not even from the browser console). You'll have to paste and execute your code after navigating to the new page, not before, which means you can't navigate to it from within your code.
You might look at tools like TamperMonkey or GreaseMonkey and such that let you run code in response to pages loading that match certain URLs.
window.location.replace() exits the current page and loads a new one. So any remaining JavaScript of the current page isn't executed anymore
Your function is working fine the only problem is window.localtion line reload the website with the url you provided so the entire page is getting reload from start and your page lost your function.
try the below to understand
function openGroupsPage() {
//window.location.replace('http://www.google.com');
setTimeout(function() {
for (i = 0; i < 100; i++) {
console.log(i)
}
} , 1000)
}
openGroupsPage()
You could add an eventListener do the document of the page which fires when the page is loaded.
document.addEventListener('DOMContentLoaded' function(e) {
// page is loaded do you fancy stuff in here
// no timeout needed
});
EDIT: Overlooked that he want to do it over the console on a random page. This won't work because on locationchange all current scripts are stopped and global objects are destroyed.
Use something like Greasemonkey for that.
Currently working on a page containing a video that has to be paused at certain points (like chapters). So I made a function that will stop the video when it hits the next "time marker" which looks like this:
function vidPause(nextMarker){
var timeMarker = nextMarker;
if(videoPlayer.currentTime >= timeMarker) {
videoPlayer.pause();
videoPlayer.removeEventListener('timeupdate', vidPause());
}
};
And I'm trying to fire it this way:
videoPlayer.addEventListener('timeupdate', vidPause(nextMarker));
But it only seems to fire when the video is loaded. Nothing happens when the video is playing (tested by using a console.log(videoPlayer.currentTime); inside the vidPause function).
Note: I need the function to be called that way so that I can remove the event listener when it hits the time marker, that way it won't stop when the user wants to play the video from that point on.
Thanks in advance for any suggestions!
The function is being called once in the addEventListener line, but that's not actually passing it as a callback.
Try this:
function videoUpdate(e) {
vidPause(nextMarker, videoPlayer.currentTime;); // Now call your function
}
function vidPause(nextMarker, timeStamp){
var timeMarker = nextMarker;
if (timeStamp >= timeMarker) {
videoPlayer.pause();
videoPlayer.removeEventListener('timeupdate', videoUpdate);
}
};
videoPlayer.addEventListener('timeupdate', videoUpdate); // Note no brackets, as it's passing a ref to the function rather than calling it
I don't know what the scope of nextMarker is, but you should be able to start console logging and find out.
I am trying to run small snippet code in JavaScript, where I want to write on the web page simple hello world each 5 seconds. I think it must be ok, but no, still I got only first hello world and no more. Could you give me a hand in this? Thanks
<script type="text/javascript">
var i=0;
function startTimer() {
window.setTimeout('refresh()',5000);
}
function refresh() {
document.write("Hello world "+i+"<br/>");
i++;
window.setTimeout('startTimer()',1);
}
startTimer();
</script>
NOTE: As Amar Palsapure has noted in this answer, the root cause of the problem was the use of document.write. In my demonstration, I use a p element to document.body.appendChild() to add the text to the screen.
You can use setTimeout(), but you have to make it contingent on the last setTimeout() that ran; so that each time the caller runs, it creates the next timeout.
setInterval() is designed to run at a "regular" interval (neither setTimeout() nor setInterval() are truly reliable in when they run); however, if the calls to setInterval() get backed up due to some other process blocking it's execution (Javascript is single-threaded), you could have issues with those queued callbacks. That's why I prefer the approach I have below.
Note, refrain from the setTimeout('funcCalled()', 100) usage; this is running an eval() on that string you're passing in, which can change the scope in which you're running the callback, as well as being considered "evil" due to security issues related to eval(). You're best to avoid it altogether.
EDIT - Modified slightly.
I have made some changes to the approach. See my comments.
// The first and last lines comprise a self-executing,
// anonymous function, eg, (function(){})();.
// This allows me to use a local function scope and not the
// global window scope, while still maintaining my variables
// due to it being a "closure" (function(){}).
(function(){
var i = 0,
timer = 5000,
// I'm just going to add this to the DOM.
text = document.createElement('p');
// This is a variable function, meaning it stores a
// reference to a function.
var helloWorld = function() {
// Here is where I add the Hello World statement
text.innerHTML += 'Hello World! Loop: ' + i++ + '<br/>';
// Them add it to the DOM.
document.body.appendChild(text);
// I added this so it wouldn't run forever.
if (i < 100) {
// A setTimeout() will be added each time the last
// was run, as long as i < 100.
// Note how I handle the callback, which is the
// first argument in the function call.
setTimeout(helloWorld, timer);
}
// I added the change so it wouldn't take so long
// to see if was working.
timer = 500;
}
// Here I use a variable function and attach it to the
// onload page event, so it will run when the page is
// done loading.
window.onload = helloWorld;
})();
http://jsfiddle.net/tXFrf/2/
The main issue is document.write. There is nothing wrong with setTimeout or rest of the code.
The reason it does not work is that once document.write is called the first time, it overwrites your existing code of setTimeout() and since there is no code so it will not work.
What you need to do is use some other means to write the value in the page, certainly no document.write...
Instead of using setInterval use setTimeout.
You can try this
<html>
<body>
<div id="clock" ></div>
<script type="text/javascript">
var i = 0,
timerHandle,
clock;
function startTimer() {
clock = document.getElementById('clock');
//You can use timerHandle, to stop timer by doing clearInterval(timerHandle)
timerHandle = self.setInterval(funRefresh, 2000);
}
var funRefresh = function refresh() {
clock.innerHTML += "Hello world " + i++ + "<br/>";
}
startTimer();
</script>
</body>
</html>
Hope this helps you.
Here is the working Code
var i = 0;
function startTimer() {
window.setInterval(refresh, 5000);
}
function refresh() {
document.write("Hello world " + i + "<br/>");
i++;
// window.setTimeout(startTimer,1);
}
startTimer();