Simple nested setTimeout() only runs once (JavaScript) - javascript

For some reason my galleryScroll() function only runs once, even though the function calls itself using setTimeout(). I'm thinking the issue may be related to scope, but I'm not sure:
http://jsfiddle.net/CYEBC/2/
$(document).ready(function() {
var x = $('#box').offset().left;
var y = $('#box').offset().top;
galleryScroll();
function galleryScroll() {
x = x + 1;
y = y + 1;
$('#box').offset({
left: x,
top: y
});
setTimeout('galleryScroll()', 100);
}
});​
The HTML:
<html>
<head>
</head>
<body>
<div id="box">
</div>
</body>
</html>​

The function galleryScroll() isn't defined in the correct scope to be evaluated in setTimeout(). If you want it running in a loop, call it in setInterval() after the function.
$(document).ready(function() {
var x = $('#box').offset().left;
var y = $('#box').offset().top;
galleryScroll();
function galleryScroll() {
x = x + 1;
y = y + 1;
$('#box').offset({
left: x,
top: y
});
}
// Call in setInterval() outside the function definition.
// Note also, I've changed the eval string 'gallerySroll()' to the function reference galleryScroll
setInterval(galleryScroll, 100);
});​
Here is the updated fiddle.

Your problem is how you're calling the galleryScroll() function in your setTimeout. Change that line to this:
setTimeout(galleryScroll, 100);
The result: http://jsfiddle.net/CYEBC/12/
Note: I'm not sure if this is the desired behavior, but it's what happens when your code is called properly.

Related

Randomize a div position

I've made a program where you press a button and a div positions itself randomly.
function Init()
{
div = document.getElementById("pixel");
spaceW = screen.height - div.height;
spaceH = screen.width - div.width;
setInterval(moveIt, 1000);
}
function moveIt()
{
div.style.top = (100*Math.random()) + "%";
div.style.left = (100*Math.random()) + "%";
}
The thing is, it only works when I use the setInterval. I only want the div to move ONCE. I'll erase the setInterval, and then what?
If you look through the documentation, you will see setInterval() fires at specific and regular intervals. If you want to only fire your function ONCE, use setTimeout() instead:
function Init()
{
div = document.getElementById("pixel");
spaceW = screen.height - div.height;
spaceH = screen.width - div.width;
setTimeout(moveIt, 1000);
}
function moveIt()
{
div.style.top = (100*Math.random()) + "%";
div.style.left = (100*Math.random()) + "%";
}
Init();
#pixel
{
width: 50px;
height: 50px;
background-color: red;
position: absolute;
}
<div id="pixel"></div>
SetInterval repeats every given interval
setTimeout runs once when the timeout expires
Sounds like you need to use setTimeout if you'd like it run once
function sayHi() {
alert('Hello');
}
setTimeout(sayHi, 1000)
see fiddle not created by me
If it works this way then declare a variable for the setInterval() then you can distroy that interval in the other function, like this varible.clearInterval()
some=setInterval(moveIt,200);//this one in caller function.
some.clearInteraval();//here this statment should be in moveIt
here you should declare some as global variable

setInterval inside of function not working

I'm pretty new to any form of coding so please forgive my ignorance, but when I use a var for my interval for a second function, it will not work correctly, I've tried my best to not have to ask, but my search is fruitless. Please help!
function click_01() {
var elem = document.getElementById('trash_02');
setInterval(frame, 10);
var width = 0
function frame(){
if (width >= 100){
clearInterval("frame");
width = 0;
} else {
width = width + 1;
elem.style.width = width + '%';
}
}
}
click_01();
Pass a function instead of a string
Just remove quote and parenthesis from function frame. If you pass with quotes it will become string and your code wont work properly.
So here goes your answer
function click_01() {
var intr=setInterval(frame, 100);//here you passed "frame()" which is string
function frame(){
let elem=document.getElementById('cls');
elem.style.width=(parseInt(elem.style.width)+1)+'px';
elem.innerHTML=parseInt(elem.style.width)+"%";
if(parseInt(elem.style.width)>=100){
elem.style.width=0;
clearInterval(intr);
elem.innerHTML='Loading complete';
}
}
}
<div id="cls" style="background-color:red;width:0px">
</div>
<div><button onclick="click_01()"> click to launch loader</botton> </div>

can't get div IDs to disappear

New to Javascript, and this one is troubling me a little. I am basically trying to make a whack-a-mole type game. Once I add the images, I want to remove them one by one. I think I have the unique IDs added, but but when I add the image removal, everything stops working. What am I doing wrong? I also thought to find other items besides the .remove, but I'm not sure what that part of the code is called (method, function, etc.) My code is below.
function addMole(){
var xPos = randomPosX();
var yPos = randomPosY();
var count=0;
$("#gamespace").append('<img src="img/roach.png" style="left: '+xPos+'px; top: '+yPos+'px;" id="img'+count+'"/>');
var r=Math.floor(Math.random()*2000);
t=setTimeout("addMole();", r);
$("#gamespace").remove("img'+count+'"").removeAttribute(img'+count+'");
count++;
}
Everything stops working because this line is not valid JavaScript:
$("#gamespace").remove("img'+count+'"").removeAttribute(img'+count+'");
check your quotes: while '...' and "..." are interchangeable, single " and ' are not.
Another problem is, after fixing the above, that your code logic doesn't pan out: you are adding an image then immediately removing it. I don't quite know what you are trying to do so I can't rewrite it for you; the best I can do is tell you to define your flow more in detail.
Finally, when you are creating elements programmatically, it is generally nicer and less failure-prone to keep element references rather than mess with IDs.
var $gamespace = $('#gamespace');
var $img = $('<img>').css({
left: left,
top: top
}).appendTo($gamespace);
// ...
$img.remove();
use
$("#gamespace").find("#img'"+count+"'").remove();
instead of
$("#gamespace").remove("img'+count+'"").removeAttribute(img'+count+'");
or.. while image ID is unique you can use directly
$("#img'"+count+"'").remove();
You had some invalid quotations:
function addMole(){
var xPos = randomPosX();
var yPos = randomPosY();
var count=0;
$("#gamespace").append('<img src="img/roach.png" style="left: '+xPos+'px; top:' + yPos + 'px;" id="img'+count+'"/>');
var r=Math.floor(Math.random()*2000);
t = setTimeout(addMole, r);//is t defined already?
$("#gamespace").remove("#img" + count).removeAttribute("img" + count);//why you need removeAttribute
count++;
}
move the count declaration outside of your function... it's reset to 0 each time it runs.
Also, would add 300 to your random number for remove, so it will show at elast 1/3 second... beyond this, you can reference the function directly in the setTimeout(addMole,r); ... you're creating an extra wrapper that isn't needed.
var count = -1; //first is 1
function addMole(){
count++;
var rnd;
var xPos = randomPosX();
var yPos = randomPosY();
var img = $('<img src="img/roach.png" />')
.css({left:xPos,top:yPos})
.addClass('mole')
.attr('id','img'+count);
img.click(addPoints);
$('#gamespace').append(img);
//remove image at random interval
rnd = 300 + Math.floor(Math.random() * 2000);
setTimeout(removeImageShim(img),rnd);
//add next mole at random interval
rnd = Math.floor(Math.random() * 2000);
setTimeout(addMole, rnd);
}
function addPoints() {
//TODO: addPoints
$(this).remove();
}
function removeImageShim(img) {
return function(){
img.remove();
}
}

setTimeout issue

I'm trying to create a jquery fadeto type of effect in Javascript, but am having an issue with my setTimeout command.
Here is the code:
function textfade(y) {
var x = document.getElementById("test");
var y;
if (y == undefined) {
y = 1.0;
}
x.style.opacity = y;
y -=0.1;
setTimeout(function(){ textfade(y); }, 50);
}
The problem is x.style.opacity = y.
Without that, the timeout runs fine. With it, however, it runs through the function one time and then dies. While I feel like it's a simple error, I am out of ideas for fixing it.
Any advice would be greatly appreciated.
Thank you in advance.
You're re-declaring y each time textfade() is executed, effectively destroying / resetting the passed parameter.
Remove:
var y;
Ensure that you are running it after test element is already available. Here it works fine: http://jsfiddle.net/3yDMP/ . And here: http://jsfiddle.net/3yDMP/3/ - no , because function is called in head, not in onload (like in first fiddle), when dom is not ready yet and is not available.
So, in your could be
<head>
<script>
function textfade() {...}
</script>
</head>
<body onload="textfade()">
<div id="test"> ... </div>
IMHO this would be better with the setTimeout calling an internal closure where the current opacity level is maintained outside of the fade function itself, so you don't have to pass it around.
function textfade(el) {
if (typeof el === "string") {
el = document.getElementById(el);
}
var opacity = 1.0;
(function fade() {
el.style.opacity = opacity;
opacity -= 0.1;
if (opacity > 0) {
setTimeout(fade, 50);
}
})();
}
demo at http://jsfiddle.net/alnitak/TQHYj/

How do you get cursor position on setInterval() callback

I need to record the mouse position every n seconds, but jQuery seems to only offer ways to retrieve the x and y position values when there is a mouse event. Can this be done with setInterval()?
EDIT - I'm thinking to set a setInterval() to increase a value every n seconds (say 'i'), and then on mousemove record the current i alongside the x and y values. There really should be an easier way than this though
What you can do is bind a function to the mousemove event on the document, and inside the function set a global variable with the mouse position. then every interval you can read the mouse position.
example:
$(document).ready(function () {
var mousePosition = {'x': 0, 'y': 0};
$(document).bind('mousemove', function(e) {
mousePosition = {'x': e.pageX, 'y': e.pageY};
});
setInterval(function () {
// do something with mousePosition
}, 1000);
});
This should help.
http://jsbin.com/owifu3/
http://docs.jquery.com/Tutorials:Mouse_Position
Might as well paste the code...
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$(document).mousemove(function(e){
$('#status').html(e.pageX +', '+ e.pageY);
});
})
</script>
<body>
<h2 id="status">
0, 0
</h2>
</body>
</html>
Here is a solution that doesnt use jQuery. Although I do prefer the jq option:
http://www.codelifter.com/main/javascript/capturemouseposition1.html
You could make usage of the .timeStamp property which is available in the event object:
var stored = 0;
$( document ).mousemove(function( event ) {
if( event.timeStamp - stored >= 2000 ) {
console.log('stored!');
stored = event.timeStamp;
}
});
Of course, that technique would only store data while moving the mouse. On idle time, nothing happens. If you also need idle position's you really need to go with an interval timer.
jQuery(document).ready(function(){
var myx, myy;
$(document).mousemove(function(e){
myx = e.pageX;
myy = e.pageY);
});
window.setInterval(function() {
$('#status').html('mouse position is '+myx+','+myy);
}, 1000);
});
I had to do something like that once, and I used this kind of a hacky solution:
document.onmousemove=function(){
x = e.pageX;
y = e.pageY;
}
setInterval(function(){
array.push(x+','+y);
},'1000');
The length of this array will be your i. You can get the individual terms using the split method.
Demo that just prints them to a div
Two solutions, neither of which uses Jquery:
http://javascript.about.com/library/blmousepos.htm
http://hartshorne.ca/2006/01/23/javascript_cursor_position/

Categories

Resources