Javascript gradual width increase - javascript

I'm trying to gradually increase the elements of 2 id's in javascript using a Timeout. I can get one working but when trying to call another element into the same function it only does one iteration then crashes after the first recursive call.
I'm passing two id's for the elements. and I want the left element to gradually increase while the right element gradually increases in width.
Heres what ive got
function grow(elementL, elementR)
{
var htL = parseInt(document.getElementById(elementL).style.width,10);
var htR = parseInt(document.getElementById(elementR).style.width,10);
var movementL = htL + 5;
var movementR = htR - 5;
document.getElementById(elementL).style.width = movementL + 'px';
document.getElementById(elementR).style.width = movementR + 'px';
if (movementL > 1000) {
clearTimeout(loopTimer);
return false;
}
var loopTimer = setTimeout('grow(\''+elementL+','+elementR+'\')',50);
}

You could simplify this (removing the script-generation) by using setInterval -- this repeats the function call until you cancel it.
function grow(elementL, elementR)
{
var loopTimer = setInterval(function() {
if (!growStep(elementL, elementR)) {
clearInterval(loopTimer);
}
}, 50);
}
function growStep(elementL, elementR) {
var htL = parseInt(document.getElementById(elementL).style.width,10);
var htR = parseInt(document.getElementById(elementR).style.width,10);
var movementL = htL + 5;
var movementR = htR - 5;
document.getElementById(elementL).style.width = movementL + 'px';
document.getElementById(elementR).style.width = movementR + 'px';
if (movementL > 1000) {
return false;
}
return true;
}
(Fiddle)
Edit
Yeah, I guess the only problem with the OP code is that it passes a string to setTimeout, rather than the function itself:
var loopTimer = setTimeout(function() {
grow(elementL, elementR);
},50);

setTimeout('grow(\''+elementL+','+elementR+'\')',50)
would need to be
setTimeout('grow(\''+elementL+'\',\''+elementR+'\')',50)
// ^^ ^^
to work. But don't do that. Pass a function expression to setTimeout:
setTimeout(function() {
grow(elementL, elementR);
}, 50)

Related

Javascript Closure functions

So I'm new to javascript and I am looking for a way to count how many times a function is executed. The code randomly generates a square or circle and displays from the shape is shown to when you click it (reactionTime). That works fine and dandy.
But I'm looking for a way to keep track of the number of times a shape is clicked and then eventually the cumulative time to calculate average time per click. If it helps, I come from a pretty good C++ background.
To count number of clicks, I was thinking of adding a closure function.
From here: How do I find out how many times a function is called with javascript/jquery?
myFunction = (function(){
var count = 0;
return function(){
count++
alert( "I have been called " + count + " times");
}
})();
And from here: Function count calls
var increment = function() {
var i = 0;
return function() { return i += 1; };
};
var ob = increment();
But I tried a global variable and several variations of closure functions to no avail (look for the comments). I tried putting the closure function in other functions. And I also tried something like:
var increment = makeBox();
I'm wondering if anyone can guide me in the right direction. It would be much appreciated!
var clickedTime; var createdTime; var reactionTime;
var clicked; var avg = 0;
avg = (avg + reactionTime) / clicked;
document.getElementById("clicked").innerHTML = clicked;
document.getElementById("avg").innerHTML = avg;
function getRandomColor() {
....
}
function makeBox() { // This is the long function that makes box
createdTime = Date.now();
var time = Math.random();
time = time * 3000;
///////// var increment = function () {
var i = 0;
//return function() { return i += 1; };
i++;
return i;
///////// };
// clicked++; /////////// global variable returns NaN
// console.log(clicked);
// alert("Clicked: "+clicked);
setTimeout(function() {
if (Math.random() > 0.5) {
document.getElementById("box").style.borderRadius="75px"; }
else {
document.getElementById("box").style.borderRadius="0px"; }
var top = Math.random(); top = top * 300;
var left = Math.random(); left = left * 500;
document.getElementById("box").style.top = top+"px";
document.getElementById("box").style.left = left+"px";
document.getElementById("box").style.backgroundColor = getRandomColor();
document.getElementById("box").style.display = "block";
createdTime = Date.now();
}, time);
}
ob = increment(); //////////////////////// I think this gives me 1 every time
alert("Increment: "+ob); //////////////////
document.getElementById("box").onclick = function() {
clickedTime = Date.now();
reactionTime= (clickedTime - createdTime)/1000;
document.getElementById("time").innerHTML = reactionTime;
this.style.display = "none";
makeBox();
}
makeBox();
You have a few problems but to answer your question:
You're not defining clicked as a number (or any other type) so trying to perform an operation on undefined returns NaN...because well, it's not a number.
Your second attempt var i = 0; won't work because i is re-defined on each function call.
You should be able to use your gobal variable clicked as long as you set it to zero.
Here is an example that shows how a closure can count calls to a function:
function add5(y) {
//A totally normal function
return y + 5;
}
var counter = 0, /*a counter scoped outside of the function counter function*/
trackedAdd5 = (function (func) {
/*This anonymous function is incrementing a counter and then calling the function it is passed*/
return function () {
counter++;
/*The trick is this function returns the output of calling the passed in function (not that it is applying it by passing in the arguments)*/
return func.apply(this, arguments);
}
})(add5); /*calling this tracking function by passing the function to track*/
document.getElementById('run').addEventListener('click', function () {
/*Here we are treating this new trackedAdd5 as a normal function*/
var y = document.getElementById('y');
y.value = trackedAdd5(parseInt(y.value, 10));
/*Except the outer counter variable now represents the number of times this function has been called*/
document.getElementById('counter').value = counter;
});
<label> <code>y = </code>
<input id='y' value='0' />
<button id='run'>add5</button>
</label>
<br/>
<label><code>add5()</code> was called
<input readonly id='counter' value='0' />times</label>
makeBox.click = 0; // define the function's counter outside the function
makeBox.click++; // replace the `i` usage with this inside the function
About ob = increment();: it is used erroneously (redefines ob many times);
var ob = increment(); // define it once
ob(); // increments the counter
// another way to define `increment`:
var increment = (function () {
var i = 0;
return function () {
return i += 1;
};
})();
ob = increment(); // ob becomes 1 initially
ob = increment(); // ob becomes 2, etc.

Image animation with speed control

We have some problem with our image animation with speed control.
It make use of a timeout to change the image, but we want to change the timeout value with a slider, but for some sort of reason, it doesn't work. Can someone help us out ?
We have a Jfiddle here: http://jsfiddle.net/Kbroeren/fmd4xbew/
Thanks! Kevin
var jArray = ["http://www.parijsalacarte.nl/images/mickey-mouse.jpg", "http://www.startpagina.nl/athene/dochters/cliparts-disney/images/donad%20duck-106.jpg", "http://images2.proud2bme.nl/hsfile_203909.jpg"];
var image_count = 0;
function rollover(image_id, millisecs) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
rollover("img1", 200);
$(function () {
var value;
var $document = $(document),
$inputRange = $('input[type="range"]');
// Example functionality to demonstrate a value feedback
function valueOutput(element) {
var value = element.value,
output = element.parentNode.getElementsByTagName('output')[0];
output.innerHTML = value;
}
for (var i = $inputRange.length - 1; i >= 0; i--) {
valueOutput($inputRange[i]);
};
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
rollover("img1", 200);
});
// end
$inputRange.rangeslider({
polyfill: false
});
});
You keep creating more and more infinite function calls without stopping them.
After you call your function the first time, it keeps calling itself.
then you call it again with different interval (millisecs) and it will also start call itself....
You can try two different approach.
1.Use setInterval instead of setTimeout. Use clearInterval to clear the interval before setting it with a new value.
/// Call animation() every 200 ms
var timer = setInterval("Animation()",200);
function ChageSpeed(miliseces){
///Stop calling Animation()
clearInterval(timer);
/// Start calling Animation() every "miliseces" ms
timer = setInterval("Animation()",miliseces);
}
function Animation(){
/// Animation code goes here
}
2.Or, Instead, Set your interval as a global variable (not cool) and just change it value when the user want to change the animation speed.
var millisecs = 200;
function rollover(image_id) {
var image = document.getElementById(image_id);
image.src = jArray[image_count];
image_count++;
if (image_count >= jArray.length) {
image_count = 0;
}
var timeout = setTimeout("rollover('" + image_id + "'," + millisecs + ");", millisecs);
}
$document.on('change', 'input[type="range"]', function (e) {
valueOutput(e.target);
millisecs = YourNewValue;
});

setInterval: changing numbers in function depending on times that event has occured

I need to figure out how to use setInterval() to make text increase 1px(font-size) every 1000 ms. Here's my setup:
function boom() {
var fwuff = document.getElementById("fwuff");
fwuff.style.display="block";
fwuff.style.textAlign="center"
setInterval(function(){
fwuff.style.fontSize=??
}, 1000);
}
What I don't know is what to put in the fwuff.style.fontSize so I can get the size to increase every time the event occurs. Does anyone understand and know how to do this?
Just use a variable :
function boom() {
var fwuff = document.getElementById("fwuff");
var myAwesomeVar = 10; //Base font size
fwuff.style.display="block";
fwuff.style.textAlign="center"
setInterval(function(){
fwuff.style.fontSize= myAwesomeVar + "px";
myAwesomeVar++;
}, 1000);
}
You can use a global variable or get the current fontSize in order to change it. Using a global variable will be slightly more efficient, however if you do not know the size of the font you are changing, you can use the fontSize of the element.
Fiddle
Getting then setting the fontSize:
function boom() {
var fwuff = document.getElementById("fwuff");
var myAwesomeVar = 10; //Base font size
fwuff.style.display="block";
fwuff.style.textAlign="center";
setInterval(function(){
curFontSize = $('#fwuff').css('fontSize');
FontSizeNumber = parseInt(curFontSize);
newFontSizeNumber = FontSizeNumber + 1 + 'px';
$('#fwuff').css('fontSize', newFontSizeNumber);
}, 1000);
}
or alternatively, you could use a variable:
function boom() {
var fwuff = document.getElementById("fwuff");
var myAwesomeVar = 10; //Base font size
fwuff.style.display="block";
fwuff.style.textAlign="center";
fontSizeVar = 12;
setInterval(function(){
fontSizeVar++;
newFontSizeVal = fontSizeVar + 'px';
$('#fwuff').css('fontSize', newFontSizeVal);
}, 1000);
}
Note: the question was tagged jquery. If this was accidental and you want me to convert to traditional JS, just ask.

JavaScript simple parameter error

function moveDoi(n) {
var delay = -1;
var left = document.getElementById("One");
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};
In this code I have n as a parameter of the function, that is used in the if conditional statement.
For this function i need to have one more parameter x that will change the "One" so i need to obtain something like this: document.getElementById(""+x+"") . However, this is not working?
How can I add one more parameter to the function that needs to be in quotes (" ") in function?
First, you need to pass x into the function. Then, you simply need to reference it when calling document.getElementById. There are is no need to append/prepend quotes, since x is already a string.
function moveDoi(n, x) {
var delay = -1;
var left = document.getElementById(x);
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};

Setting a time for flicker animation on img

I'm using this code to make my logo flicker on my website. But It becomes annoying when it continues to flicker while browsing, how can I set a time to allow it to flicker for something like the first 15seconds on page load, then stops?
JS code I'm using:
$(document).ready(
function(){
var t;
const fparam = 100;
const uparam = 100;
window.flickr = function(){
if(Math.round(Math.random())){
$("#logodcoi").css("visibility","hidden");
t = setTimeout('window.unflickr()',uparam);
}
else
t = setTimeout('window.flickr()',fparam);
}
window.unflickr = function(){
if(Math.round(Math.random())){
$("#logodcoi").css("visibility","visible");
t = setTimeout('window.flickr()',fparam);
}
else
t = setTimeout('window.unflickr()',uparam);
}
t = setTimeout('window.flickr()',fparam);
});
You could have a counter, which you then use to decide whether you want to set another timeout. As a side note, you should never add functions to window and then passing a string to setTimeout. Always just pass the function itself:
$(document).ready(function(){
var t;
var amount = 0;
const fparam = 100;
const uparam = 100;
function timeout(f, t) { // this function delegates setTimeout
if(amount++ < 150) { // and checks the amount already (un)flickered
setTimeout(f, t); // (150 * 100 ms = 15 s)
}
}
var flickr = function(){
if(Math.round(Math.random())){
$("#logodcoi").css("visibility","hidden");
t = timeout(unflickr,uparam);
}
else
t = timeout(flickr,fparam);
};
var unflickr = function(){
if(Math.round(Math.random())){
$("#logodcoi").css("visibility","visible");
t = timeout(flickr,fparam);
}
else
t = timeout(unflickr,uparam);
};
t = timeout(flickr,fparam);
});
I see you're using jquery, you could use the following, if I remember correctly, all the stuff I use below has been in jquery since 1.0, so you should be good:
counter = 1;
function hideOrShow(){
$(".classToSelect").animate({"opacity": "toggle"}, 100);
counter = counter +1;
if (counter >= 21) clearInterval(flickerInterval);
}
flickerInterval = setInterval(hideOrShow, 100);
Change the selector, animation duration, and variable names to whatever you fancy/need.

Categories

Resources