I can't use my function in Javascript - javascript

I'm getting error with my function change_slide().
ReferenceError: change_slide is not defined on line 24:1.
My code is here:
$(document).ready(function() {
function change_slide() {
number = pclass.charAt(6);
number = parseInt(number);
if (number == 5) number = 1;
else number++;
$('.picks').removeClass(pclass);
pclass = 'bgpick' + number;
$('.picks').addClass(pclass);
}
var random = Math.floor((Math.random() * 5) + 1);
var pclass = 'bgpick' + random;
var number;
$('.picks').addClass(pclass);
setInterval('change_slide()', 3000);
$('.next').on('click', function() {
change_slide();
});
});
change_slide() on click .next works, in setInterval doesn't work.

When you use a character string argument to setInterval, the Javascript code is executed in the global environment. You should pass a function reference instead of a character string, then it will be evaluated in the local environment.
setInterval(change_slide, 3000);
Note that you should not put parentheses after change_slide here. That will call the function immediately, instead of passing a reference to the function.

Take the function declaration out of document ready function,
Also change
setInterval('change_slide()', 3000);
To
setInterval(change_slide, 3000);
Here is modified code
$(document).ready(function() {
var random = Math.floor((Math.random() * 5) + 1);
var pclass = 'bgpick' + random;
var number;
$('.picks').addClass(pclass);
setInterval(change_slide, 3000);
$('.next').on('click', function() {
change_slide();
});
});
function change_slide() {
number = pclass.charAt(6);
number = parseInt(number);
if (number == 5) number = 1;
else number++;
$('.picks').removeClass(pclass);
pclass = 'bgpick' + number;
$('.picks').addClass(pclass);
}

Related

Why does my random number function always return same output?

I have the following code:
var lives = 10;
var score = 0;
var input = $('#input');
var board = $('#board');
var validate = $('#validate');
function randomNum(min, max) {
return Math.random() * (max - min) + min;
}
var levelOne = (randomNum(0, 999));
var levelTwo = (randomNum(999, 1999));
$('#generate').click(function () {
if (score > 1) {
board.html(levelOne);
console.log(levelOne)
setTimeout(function () {
board.fadeOut();
}, 3000);
} else {
board.html(levelTwo);
console.log(levelTwo)
setTimeout(function () {
board.fadeOut();
}, 3000);
}
});
The first number gets it output as expected, but if I keep on generating numbers, the logs say it's the same number plus I can't see it in the screen (the timeout is not working as well?). I've done this game in Objective-C but now in JS something is missing in my logic. Can someone give me a hint?
EDIT: I've tried this
$('#generate').click(function () {
var levelOne = (randomNum(0, 999));
if (score > 1) {
board.html(levelOne);
console.log(levelOne)
setTimeout(function () {
board.fadeOut();
}, 3000);
} // etc
}
and also inside the if. I don't understand why I get always the same number.
You're caching the variables levelOne and levelTwo outside of your click handler so random numbers are only generated once, if you're like them to be repeatedly regenerated put those lines inside your click handler like so:
var lives = 10;
var score = 0;
var input = $('#input');
var board = $('#board');
var validate = $('#validate');
function randomNum(min, max) {
return Math.random() * (max - min) + min;
}
$('#generate').click(function () {
if (score > 1) {
var levelOne = randomNum(0, 999);
board.html(levelOne);
console.log(levelOne)
setTimeout(function () {
board.fadeOut();
}, 3000);
} else {
var levelTwo = randomNum(999, 1999);
board.html(levelTwo);
console.log(levelTwo)
setTimeout(function () {
board.fadeOut();
}, 3000);
}
});

Using setInterval as a counter

I'm trying to create a page that changes every 10 seconds 4 times and then begins again. To do this I made a counter and passed it along with my function. It doesn't even seem like its loading.
I tried using <body onload="start()"> as well.
<script>
var i = 1;
function start(){
i = setInterval(changeEdu, 10000, i);
}
function changeEdu(i){
if(i == 4){
i = 1;
}else{
i++;
}
document.getElementById("edu1").src = "left" + i + ".jpg";
document.getElementById("edu2").src = "right" + i + ".jpg";
return i;
}
</script>
By declaring i as a parameter of your function, your increment will only mutate the local variable and not your global state. Also the return value is ignored.
var i = 1;
function start() {
setInterval(changeEdu, 10000);
}
function changeEdu() {
// ^^
if (i == 4) {
i = 1;
} else {
i++;
}
document.getElementById("edu1").src = "left" + i + ".jpg";
document.getElementById("edu2").src = "right" + i + ".jpg";
}
I believe it is because you are reassigning variable i at the onset of the start() function. setInterval returns a number that is used to cancel the function with the clearInterval(theNumber) function.
I am also quite new to JS, but I would try to delete the reassignment in the start() function and try again.
That is not how setInterval works, it doesn't return your return value.
You need to create a closure.
Also, your startInterval() is never called.
Change it to this and it works:
<script>
(function(){
var i = 1;
function changeEdu(){
if(i == 4){
i = 1;
}else{
i++;
}
// document.getElementById("edu1").src = "left" + i + ".jpg";
// document.getElementById("edu2").src = "right" + i + ".jpg";
console.log(i);
}
setInterval(changeEdu, 10000);
})();
</script>

setTimeout and setInterval

I want to make this counter starts working within 5 seconds of being on the page, but I can not link the setTimeout with setInterval , you would know how could I?
Try to wrap your interval with the setTimeout function:
// interval variable
var cycle = 10;
// variable for the interval since we are invoking it within a function, the callMeEverySecond function can't reach it
var t;
var callMeEverySecond = function() {
cycle--;
// Logs the Date to the console
console.log(new Date());
if(cycle === 0) {
console.log("stop this");
clearInterval(t);
// do something further.
}
}
// Start the timeout after 5 seconds
setTimeout(function() {
// call the function 'callMeEverySecond' each second
t = setInterval(callMeEverySecond, 1000);
}, 5000);
http://devdocs.io/dom/window.settimeout
And a small tutorial: http://javascript.info/tutorial/settimeout-setinterval
Is this ok
var tiempoInicial = 10;
function tiempo() {
document.getElementById('contador').innerHTML='Puedes continuar en ' + tiempoInicial + ' segundos.';
if(tiempoInicial==0) {
clearInterval(t);
document.getElementById("contador").innerHTML = "<p id=\"forumulario\" onclick=\"goToForm1()\">Continuar</p>";
}
}
function iniciar() {
var t = setInterval(tiempo,1000);
clearTimeout(ini);
}
var ini = setTimeout(iniciar, 5000);
Sorry, I tried out the code above and it didn't work so I changed it a bit.
This is the new code.
var tiempoInicial = 10;
function tiempo() {
document.getElementById('contador').innerHTML='Puedes continuar en ' + tiempoInicial + ' segundos.';
tiempoInicial--;
if(tiempoInicial < -1) {
clearInterval(t);
document.getElementById("contador").innerHTML = "<p id=\"forumulario\" onclick=\'goToForm1()\'>Continuar</p>";
}
}
function iniciar() {
t = setInterval(tiempo,1000);
clearTimeout(ini);
}
var ini = setTimeout(iniciar, 5000);

Why are all images be changed to the first input

<script type="text/javascript">
var interval;
$('#105').mouseover(function()
{ mouseOver('105'); });
$('#105').mouseout(function()
{ mouseOut('105') ;});
function mouseOver(videoId)
{ var num = 2;
interval = setInterval(function()
{ $('#'+videoId).attr('src', '../thumbs/268255615/268255615.'+num+'.jpg');
if(num == 12)
{ num = 1; }
else
{ num++; }},500); }
function mouseOut (videoId)
{ clearInterval(interval); $('#'+videoId).attr('src', '../thumbs/268255615/268255615.1.jpg'); }
</script>
<script type="text/javascript">
var interval;
$('#104').mouseover(function()
{ mouseOver('104'); });
$('#104').mouseout(function()
{ mouseOut('104') ;});
function mouseOver(videoId)
{ var num = 2;
interval = setInterval(function()
{ $('#'+videoId).attr('src', '../thumbs/325082397/325082397.'+num+'.jpg');
if(num == 12)
{ num = 1; }
else
{ num++; }},500); }
function mouseOut (videoId)
{ clearInterval(interval); $('#'+videoId).attr('src', '../thumbs/325082397/325082397.1.jpg'); }
</script>
The code above is a JavaScript image rotator. The problem with the code is that the last image path always overwrites the image paths before it.
For example if image path one = thumbs/imagea.jpg and if path two = thumbs/imageb.jpg path one ("thumbs/imagea.jpg")then becomes path two on hover becomes ("thumbs/imageb.jpg")
This script worked at one point trying to figure out what is wrong or been changed any ideas?
This is quite obvious: you are redefining mouseOver as a function. The second time you define it, it overwrites the first function. This is because mouseOver is defined on window-scope. Splitting it up in two blocks does not change that. Also note that "interval" is also being defined twice, so a name clash will also occur here.
A solution would be to either use closures, change the name of one of either functions or merge the two functions into one.
Closures are done by wrapping each script in the following block:
(function() {
// your script here
}());
A merged function would be:
var i, setupImage, images;
images = [
{ "id" : "#104", "prefix" : "../thumbs/325082397/325082397." },
{ "id" : "#105", "prefix" : "../thumbs/268255615/268255615." }
];
setupImage = function (image) {
'use strict';
var interval;
$(image.id).mouseover(function () {
var num = 2;
interval = setInterval(function () {
$(image.id).attr('src', image.prefix + num + '.jpg');
if (num === 12) {
num = 1;
} else {
num += 1;
}
}, 500);
});
$(image.id).mouseout(function () {
$(image.id).mouseout(function () {
clearInterval(interval);
$(image.id).attr('src', image.prefix + '1.jpg');
});
});
};
for (i = 0; i < images.length; i += 1) {
setupImage(images[i]);
}

Run a function a specified number of times

function runAgain()
{
window.setTimeout(foo, 100);
}
function foo()
{
//Do somthing
runAgain();
}
I can use the above code to run a function infinite number of times with an interval of one second.
What is the standard way of running a function defined number of times. Lets say, I want foo() to be run 5 times with an interval of 1 second.
EDIT It's said that global variables should be avoided in Javascript. Isn't there a better way?
With input from answers, I created a function like this: (Working Example: http://jsbin.com/upasem/edit#javascript,html )
var foo = function() {
console.log(new Date().getTime());
};
var handler = function(count) {
var caller = arguments.callee;
//Infinite
if (count == -1) {
window.setTimeout(function() {
foo();
caller(count);
}, 1000);
}
if (count > 0) {
if (count == 0) return;
foo();
window.setTimeout(function() {
caller(count - 1);
}, 100);
}
if (count == null) {foo(); }
};
handler(-1); //Runs infinite number of times
handler(0); //Does nothing
handler(2); //Runs two times
handler(); //Runs foo() one time
var counter = 1;
function foo()
{
if (counter < 5){
counter++
window.setTimeout(foo, 1000);
}
}
foo()// it will run 5 times;
LIVE DEMO
Version with "static variable":
function foo() {
if (typeof foo.counter == 'undefined') {
foo.counter = 0;
}
alert("Run No. " + (++foo.counter));
if (foo.counter < 5) {
setTimeout(function() {
foo(foo.counter + 1);
}, 400);
}
}
foo();
LIVE DEMO
Version with hidden input
function foo() {
var counter = document.getElementById('counter');
var counterValue = parseInt(counter.value, 10);
alert('Run No. ' + counterValue);
if (counterValue< 5) {
counter.value = counterValue + 1;
window.setTimeout(foo, 400);
}
}
foo();​
LIVE DEMO
Version with closure :
var x = function() {
var counter = 1;
(function foo() {
alert('Run No. ' + counter);
if (counter < 5) {
counter++;
setTimeout(foo, 400);
}
})();
};
x();​
LIVE DEMO
Assuming you have a function:
var foo = function() {
...
};
or if you prefer:
function foo() {
...
}
you could invoke it 5 times at intervals of 1 second like that:
(function(count) {
if (count < 5) {
// call the function.
foo();
// The currently executing function which is an anonymous function.
var caller = arguments.callee;
window.setTimeout(function() {
// the caller and the count variables are
// captured in a closure as they are defined
// in the outside scope.
caller(count + 1);
}, 1000);
}
})(0);
And here's a live demo.
use a global variable and increment it in the function foo() to count the number of times it has been called.
var counter=0;
function runAgain()
{
window.setTimeout(foo, 1000);
}
function foo()
{
//Do somthing
if((++counter)<5)
runAgain();
}
To avoid polluting the global environment with additional variables, you can wrap it in an anonymous function:
(function() {
var counter = 0;
function foo() {
// do stuff
if ((++counter) < 5) window.setTimeout(foo, 1000);
}
})();
function call (func, arg) {
return {
func,
arg,
times: function (num) {
let counter = 0;
while (counter < num) {
this.func(this.arg);
counter += 1;
}
}
};
}
Then to use it, you can do
call(yourFunction).times(10)
or, if you need to enter an argument:
call(yourFunction, arg).times(10)

Categories

Resources