If possible I'd like to use to remove count and use an argument in self.addOrbitTrap(). At the moment for testing my code does something like this:
Bbrot.prototype.findMSet = function() {
//...code
var self = this;
canvasInterval = setInterval(function() {
self.addOrbitTrap();
}, 0);
}
var count = 0;
Bbrot.prototype.addOrbitTrap = function() {
//...code
if (count === 100) {
// Call a different function. That's why I use count
}
count++;
}
Edit: To be more specific, count is used in my code to count how many times addOrbitTrap() successfully runs (it does not add an orbit trap if a randomly selected pixel is a part of the Mandelbrot Set). After it runs some number of times, I call a different function (from within addOrbitTrap()). I would rather not use a global variable because count is not used anywhere else.
You could introduce count as a local variable inside findMSet that you pass to addOrbitTrap(); at each interval the value will be increased:
Bbrot.prototype.findMSet = function() {
//...code
var self = this,
count = 0;
canvasInterval = setInterval(function() {
self.addOrbitTrap(++count);
}, 0);
}
Handling the value is simple:
Bbrot.prototype.addOrbitTrap = function(count) {
//...code
if (count === 100) {
// Call a different function. That's why I use count
}
}
just make the variable on the object and use it.
Bbrot.prototype.count = 0;
Bbrot.prototype.findMSet = function() {
//...code
var self = this;
canvasInterval = setInterval(function() {
self.addOrbitTrap();
}, 0);
}
Bbrot.prototype.addOrbitTrap = function() {
if(ranSuccessful)
this.count++;
}
Bbrot.prototype.someOtherFunc = function() {
return this.count;
}
Related
Im having trouble getting my second function to react to the changes the first function brings.
var jumbotron = function(){
var jumbotronCounter = 1
var jumbotronSwitch = function(){
var jumbotronTimer = function(){
jumbotronCounter++
}
jumbotronTimer();
if (jumbotronCounter > 3){
jumbotronCounter = 1
}
console.log(jumbotronCounter);
}
setInterval(jumbotronSwitch,7000);
var jumbotronListener = function(){
if(jumbotronCounter = 1){
console.log('first');
}else if(jumbotronCounter = 2){
console.log('second');
}else if(jumbotronCounter = 3){
console.log('third');
}
};
jumbotronListener();
}
jumbotron();
Id like to use "jumbotronListener" to run some code when "jumbotronCounter" changes
jumbotronListener is indeed only running once. You can, instead, run it every time the interval runs:
var jumbotron = function () {
var jumbotronCounter = 1;
var jumbotronSwitch = function () {
var jumbotronTimer = function () {
jumbotronCounter++;
};
jumbotronTimer();
if (jumbotronCounter > 3) {
jumbotronCounter = 1;
}
// Execute the listener every time the interval runs
jumbotronListener();
console.log(jumbotronCounter);
};
setInterval(jumbotronSwitch, 7000);
// Run for the first time if you wish:
jumbotronListener();
// Set this as function so you can 'use it before declaring it'
function jumbotronListener() {
// You had invalid operators. = assigns and === compares (strictly)
if(jumbotronCounter === 1) {
console.log('first');
} else if(jumbotronCounter === 2) {
console.log('second');
} else if(jumbotronCounter === 3) {
console.log('third');
}
}
};
jumbotron();
You also had some missing semicolons in there, sometimes it's not a problem since JavaScript auto-inserts them, but sometimes it is, so it's a good idea to always make sure to manually insert them where they go.
I am trying to make a JS function that flickers an element. I use a setInterval() for timing, but it gives the error message Uncaught TypeError: Cannot read property 'opacity' of undefined.
When I try to modify the opacity not with a timer, but "by hand", that works...
What am I doing wrong?
Usage:
document.getElementById('idOfTheElement').startFlicker();
The function:
Element.prototype.startFlicker = function() {
var blinkInterval = setInterval(function() {
if (parseInt(this.style.opacity) === 0) {
this.style.opacity = 1;
} else {
this.style.opacity = 0;
}
}, 50);
};
Try this
Element.prototype.startFlicker = function() {
var self = this;
var blinkInterval = setInterval(function() {
if (parseInt(self.style.opacity) === 0) {
self.style.opacity = 1;
} else {
self.style.opacity = 0;
}
}, 50);
};
In setInterval this refers to window, you need store context (this - current element) in variable and use in setInterval
Because of the context. this.style inside the setInterval refers to the global window object.
You could always make a reference to the element itself, because inside the setInterval function, the window object is passed as this.
Instead, you should give .bind() a try. So this will be a reference to the argument of the method.
Element.prototype.startFlicker = function() {
var blinkInterval = setInterval(function() {
if (parseInt(this.style.opacity) === 0) {
this.style.opacity = 1;
} else {
this.style.opacity = 0;
}
}.bind(this), 50);
};
<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]);
}
I am trying to figure out a way to make my countdown timer restart at 25 all over again when it reaches 0. I dont know what I am getting wrong but it wont work.
Javascript
window.onload = function() {
startCountDown(25, 1000, myFunction);
}
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
//write out count
countDownObj.innerHTML = i;
if (i == 0) {
//execute function
fn();
//stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
},
pause
);
}
//set it going
countDownObj.count(i);
}
function myFunction(){};
</script>
HTML
<div id="countDown"></div>
try this, timer restarts after 0
http://jsfiddle.net/GdkAH/1/
Full code:
window.onload = function() {
startCountDown(25, 1000, myFunction);
}
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
// write out count
countDownObj.innerHTML = i;
if (i == 0) {
// execute function
fn();
startCountDown(25, 1000, myFunction);
// stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
}, pause);
}
// set it going
countDownObj.count(i);
}
function myFunction(){};
I don't see you resetting the counter. When your counter goes down to 0, it executes the function and return. Instead, you want to execute the function -> reset the counter -> return
You can do this by simply adding i = 25 under fn() :
function startCountDown(i, p, f) {
var pause = p;
var fn = f;
var countDownObj = document.getElementById("countDown");
countDownObj.count = function(i) {
// write out count
countDownObj.innerHTML = i;
if (i == 0) {
// execute function
fn();
i = 25;
// stop
return;
}
setTimeout(function() {
// repeat
countDownObj.count(i - 1);
},
pause
);
}
// set it going
in #Muthu Kumaran code is not showing zero after countdown 1 . you can update to this:
if (i < 0) {
// execute function
fn();
startCountDown(10, 1000, myFunction);
// stop
return;
}
The main reason for using setInterval for a timer that runs continuously is to adjust the interval so that it updates as closely as possible to increments of the system clock, usually 1 second but maybe longer. In this case, that doesn't seem to be necessary, so just use setInterval.
Below is a function that doesn't add non–standard properties to the element, it could be called using a function expression from window.onload, so avoid global variables altogether (not that there is much point in that, but some like to minimise them).
var runTimer = (function() {
var element, count = 0;
return function(i, p, f) {
element = document.getElementById('countDown');
setInterval(function() {
element.innerHTML = i - (count % i);
if (count && !(count % i)) {
f();
}
count++;
}, p);
}
}());
function foo() {
console.log('foo');
}
window.onload = function() {
runTimer(25, 1000, foo);
}
I have the below JavaScript code. In the function update, the this.connection resolves to undefined instead of a number. What am I doing wrong?
function Net()
{
this.connection = -1;
this.counter = 1;
this.timelastsend = -1;
setInterval( this.update, 3000);
}
Net.prototype.update = function()
{
if (this.connection > 0 && this.timelastsend > 0)
{
var now = new Date().valueOf();
if (now - this.timelastsend > 1000 * 60)
{
}
}
}
One of the problems of using this is that this is dependent on the way you call the function.
setInterval will call your update method as if it were a standalone function, and so this will be set to the global object.
If you really need to use the this functionality, rewrite your call to to setInterval as follows:
function Net() {
var self = this;
this.connection = -1;
this.counter = 1;
this.timelastsend = -1;
setInterval( function () { self.update() }, 3000);
}
This way, you’ll create a self variable which will keep referring to your object (if you’ve created it using the new operator — another reason to avoid this).
Addendum:
If you’re not actively descending lots of objects from your Net pseudoclass, I’d refactor the thing as follows:
function createNet() {
var connection = -1,
counter = -1,
timelastsent = -1,
self,
update;
update = function () {
var now;
if (connection > 0 && timelastsent > 0) {
now = new Date().valueOf();
if (now - timelastsent > 1000 * 60) {
// ... update code ...
counter += 1;
timelastsent = now;
}
}
};
setInterval(update, 3000);
return {
update: update,
getTimeLastSent: function () { return timelastsent; },
getCounter: function () { return counter; },
getConnection: function () { return connection; }
};
}
You’ll notice there is no mention of this anywhere, which means no ambiguity. I’ve included three getters for the connection, counter and timelastsent properties, but if you want those to be writable from outside the object, you could just as easily add them to the created object.