How to Change innerHTML on Interval pulling from an array? - javascript

Trying to get an element to change every x number of seconds. When I click the button it should change the innerHTML, looping through an array. The code below changes the text but displays the last result in the array.
<h1 id="header">Agent</h1>
<button id="change-header" onclick="loopHeader()">Click Me</button>
<script>
function loopHeader() {
var loopHeader = setInterval(changeText, 1000);
}
function changeText() {
var headers = ["Agent", "Expert", "Homes", "Service", "Results"];
var text = "";
var i = 0;
var x = document.getElementById("header");
for (i = 0; i < headers.length; i++) {
text = headers[i];
x.innerHTML = text;
}
}
</script>

Move the count outside of the function, and then keep looping round and resetting to 0 when at end.
function loopHeader() {
var loopHeader = setInterval(changeText, 1000);
}
var headers = ["Agent", "Expert", "Homes", "Service", "Results"];
var loopItem = 0;
function changeText() {
loopItem++;
if (loopItem == headers.length) {
loopItem = 0;
}
document.getElementById("header").innerHTML = headers[loopItem];
}
</script>
<div id="header">
</div>
<button id="change-header" onclick="loopHeader()">Click Me</button>

That's because every time you changeText is called it start changing the innerHTML of the button by the text from the array all from index 0 to the end (It's happening you just can't see it because it's happening fast). What you need is to define i outside the function and every time the function is called increment i and show its corresponding value from the array without a loop. Like this:
<button id="change-header" onclick="loopHeader()">Click Me</button>
<script>
function loopHeader() {
// if you want to start the animation just after the button is clicked, then uncomment the next line
// changeText();
var loopHeader = setInterval(changeText, 1000);
}
var i = 0; // i declared outside with the initiale value of 0
var headers = ["Agent", "Expert", "Homes", "Service", "Results"]; // this also should be outside (what's the point of redefining it every time the function is called)
function changeText() {
var x = document.getElementById("change-header"); // the id is change-header
// increment i and check if its beyond the boundaries of the loop, or just use modulo operator t prevent it from going beyond
i = (i + 1) % headers.length;
x.textContent = headers[i]; // textContent is better than innerHTML
}
</script>

Related

How to make function work multiple times

var change = function() {
var elem = document.getElementsByTagName("body");
var count = 0;
count++;
var color = "";
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
for (var i = 0; i < colors.length; i++) {
if (count == i + 1) {
color = colors[i];
}
}
elem[0].style.backgroundColor = color;
}
<button onclick="change()">Click me</button>
I want the background color of the body to change when I click the button.
But the number of variable "count" doesn't seem to increase. What should I do to make the number increase?
Declare the variabe count outside the function so that it gets the global scope whenever you update.
DEMO
var count = 0;
var change = function() {
var elem = document.getElementsByTagName("body");
count++;
console.log('##count',count);
var color = "";
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
for (var i = 0; i < colors.length; i++) {
if (count == i + 1) {
color = colors[i];
}
}
elem[0].style.backgroundColor = color;
}
<button onclick="change()">Click me</button>
Without changing your code too much, you can avoid the loop and iterate over the array by comparing the current color. This also avoids holding a count iterator.
Note:
Some browsers return backgroundColor as an rgb value (e.g., rgb( ###, ###, ###)), which is why rgb2hex is used to convert the it to the hex value like that stored in the colors array.
var change = function() {
var el = document.querySelector("body");
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
var currentColor = rgb2hex( el.style.backgroundColor );
var colorIndex = colors.indexOf( currentColor );
// If at last color, cycle back to front
if (colorIndex == colors.length-1)
colorIndex = -1;
el.style.backgroundColor = colors[colorIndex + 1];
}
/** Converts decimal to hex **/
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
/** Converts rgb string to hex string **/
function rgb2hex(rgb) {
if (rgb.search("rgb") == -1)
return rgb;
else {
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
}
<button onclick="change()">Click me</button>
Each call to your function is resetting count to 0 because you are setting it to zero on the second line of the function.
If you set it to 0 outside the function once, this will solve the count problem.
However, there is an additional problem (that you didn't mention): after counting to 7, you run out of colours in your array because count exceeds the bounds of the array. I would lose the for loop since it is unnecessary (use count to index into the array instead) and just reset count when it reaches the size of the array.
var count = 0;
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
var change = function() {
var elem = document.getElementsByTagName("body");
if (count == colors.length) {
count = 0;
}
elem[0].style.backgroundColor = colors[count];
count++;
}
<button onclick="change()">Click me</button>
The count variable has local scope, so it will not exist after the anonymous function expression referred by change variable finishes execution. For it to sustain its life time across repeated function calls on button click action it should be declared in global scope outside the anonymous function expression:
var count = 0; //now count has global scope.
var change = function() {
var elem = document.getElementsByTagName("body");
count++;
var color = "";
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
for (var i = 0; i < colors.length; i++) {
if (count == i + 1) {
color = colors[i];
}
}
elem[0].style.backgroundColor = color;
}
<button onclick="change()">Click me</button>
Note: You should also consider giving some default color inside the for loop as after 7 clicks it will be setting the backgroundColor to empty string.
var color = "#000000"; //default black color may be
To achieve expected result, use below option
No need of for loop
After 7 clicks , loop runs again
One issue with your code is, first background color will always be skipped due i+1 and after 7 clicks , it comes back to white background
var count = 0;
var colors = ["#ff6051", "#ff9f51", "#ffdf51", "#b6ff51", "#51adff", "#3e65c1", "#6414ef"];
var change = function() {
if(count == colors.length + 1){
count =0;
}
++count;
var elem = document.getElementsByTagName("body");
elem[0].style.backgroundColor = colors[count];
}
https://codepen.io/divyar34/pen/EbZxPm
You can generically count the invocations of any function by "lifting" the function (wrapping it) with a function that just does that.
This leaves you with a simple function that doesn't need to know if it is being counted, which you can wrap with a counter only when you need it.
function countingWrapper(f,reportf)
{
var counter = 0;
return function()
{
reportf( ++counter)
return f.apply(this, arguments);
}
}
function doSomething() { console.log('boo!'); }
function reportSomething(n) { console.log('did something '+ n + ' times.')}
var newDoSomething = countingWrapper(doSomething, reportSomething);
newDoSomething();
newDoSomething();
newSoSomething();

How can I use a default value for this array? The result is not displayed until the first loop

I have this code:
<span id="changeText"></span>
<script type="text/javascript">
var text = ["cool", "awesome", "outstanding"];
var counter = 0;
var elem = document.getElementById("changeText");
var refreshIntervalI = setInterval(change, 2000);
function change()
{
elem.innerHTML = text[counter];
counter++;
if (counter >= text.length) { clearInterval(refreshIntervalI); }
}
</script>
The output correctly displays each word after 2000ms, but it also takes 2sec to display the first word. How can I set a default value which will be displayed until the start of the loop?
Thanks in advance :)
Why not just like this
var text = ["cool", "awesome", "outstanding"];
var counter = 1;
var elem = document.getElementById("changeText");
elem.innerHTML = text[0];
var refreshIntervalI = setInterval(change, 2000);
function change()
{
elem.innerHTML = text[counter];
counter++;
if (counter >= text.length) { clearInterval(refreshIntervalI); }
}
Set the first value of your array as innerHTML on load and let the counter start at 1 and it should work as intended.
Try to call the function without setInterval() for the first time:
function change() {
...
}
change();

JavaScript clearInterval

I'd like to have a div become visible on a button click and have a setInterval append periods to show loading. I would also like a button to clear that interval and hide the div that shows up.
here's a fiddle
http://jsfiddle.net/4qx4r/4/
here's code:
function ProgressBar(){
var div;
var start = function(){
var count = 0,
div = $('#divNotification').show().text('Uploading').css('align','center'),
originalText = div.text(),
count = 0;
var beginCount = setInterval(function(){
var newText = div.text() + '.';
div.text(newText);
count++;
if(count > 5){
div.text(originalText);
count =0;
}
console.log(count);
},500)
}
var stop = function(){
console.log('stop');
div.hide();
window.clearInterval(beginCount);
}
this.start = start;
this.stop = stop;
}
var progressBar = new ProgressBar();
$('#btnStart').click(function(){
progressBar.start();
});
$('#btnStop').click(function(){
progressBar.stop();
});
Currently when I click btnStop I get `cannot read property hide of undefined'. How can I make this stop the interval and hide the div?
You are setting var beginCount within a function, therefore that variable is only accessible within that function.
Try declaring that variable outside or simply just remove the var part.
I would add it next to var div declaration
Also you need to replace commas with semicolons and your div is not set to the object, try the following:
var count = 0;
div = $('#divNotification');
div.show().text('Uploading').css('align','center');
originalText = div.text();
count = 0;
http://jsfiddle.net/4qx4r/6/
this works: http://jsfiddle.net/W8ySn/3/
I separated the initial div assignment:
div = $('#divNotification');
var count = 0;
div.show().text('Uploading editor').css('align','center');
originalText = div.text();
count = 0;

How to disable buttons after x amount of clicks in js?

I am trying to use Javascript to disable a button after it is clicked x amount of times. For simplicity sake lets say x = 2 for now. I cannot seem to get the counter to increment. Thank You for any help!
var $ = function (id) {
return document.getElementById(id);
}
window.onload = function () {
coke.onclick = function(){
var count =0;
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}
Where "coke" is the element ID. If i get rid of the if statement and just have coke.disabled = true, of course it works and disables after one click. I'm sure there is a core concept I am missing.
Thank You
This is happening because each time the onclick event is fired, your var count is being assigned to 0, so it will never be greater than or equal to one in your function. If you initialize the count var outside of the onclick function, it will behave as expected.
window.onload = function () {
var count = 0;
coke.onclick = function(){
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}
You need to define count outside the scope of your onclick function:
var $ = function (id) {
return document.getElementById(id);
}
var count = 0; // set initial count to 0
window.onload = function () {
coke.onclick = function(){
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}

Javascript content rotator?

I’ve got the basics of a content rotator done, the only problem is it doesn’t loop itself back to the beginning and I cannot figure out why! It is a very simple javascript script:
window.onload = function() { setInterval("transition()", 5000); }
function transition()
{
var y = document.getElementById("featured").getElementsByTagName("li");
for (var i=0;i<y.length;i++)
{
if (y[i].className == "current")
{
y[(i+1)].className = "current";
y[i].className = "";
break;
}
}
}
It keeps stopping at the end of the list, basically I just want it to loop. Any help?
You can make this a little smarter by taking advantage of the wonderful language that is Javascript:
window.onload = function() {
var y = document.getElementById('featured').getElementsByTagName('li');
var ylen = y.length, index = 0;
y[0].className = 'current';
setInterval(function() {
y[index].className = '';
index = (index + 1) % ylen;
y[index].className = 'current';
}, 5000);
};
When you pre-define the list of <li> elements like that, the function you provide for the interval timer can reference them every time the timer fires. The index variable increments up until it hits the end of the array, and then it'll be set back to zero.
try this:
if (y[i].className == "current")
{
if (y[i+1]]
y[i+1].className = "current";
else
y[0].className = "current";
y[i].className = "";
break;
}
First time you loop you set the last elements class "current". You should put something like
y[0].className = "current"
when you reach and of the loop.

Categories