Quickly change css attributes values? - javascript

I have sample code:
<div></div>
<button>
Go
</button>
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
var bgs = ['red', 'blue', 'yellow', 'green', 'black'];
$('button').click(function() {
for (var i = 0; i < bgs.length; i++) {
$('div').css('background-color', bgs[i]);
}
});
https://jsfiddle.net/e4jhwtyc/2/
What I want to achieve is that when users click the Go button, users will be able to see the background very quickly changing from red, blue, yellow, green, and then black.
But what I got was just black color when the Go button was clicked.
Am I missing something?

You need to set some timeout to see change in color otherwise it will happen too quickly.
var bgs = ['red', 'blue', 'yellow', 'green', 'black'];
$('button').click(function() {
for (var i = 0; i < bgs.length; i++) {
setTimeout(function(){
$('div').css('background-color','').css('background-color', bgs[i]);
}, 1000);
}
});

You can use setInterval() to change color on some period of time (0.3s for example) otherwise it will change instantly with your code. And when it reaches last element of array you can clearInterval() and reset counter i
var bgs = ['red', 'blue', 'yellow', 'green', 'black'];
var i = 0;
$('button').click(function() {
var x = setInterval(function() {
if (i < bgs.length) {
$('div').css('background-color', bgs[i++]);
} else {
clearInterval(x);
i = 0;
}
}, 300)
});
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>
Go
</button>

Every time there is a click event the for ends at black color. So it gets black!!!. The for is to fast if you compare that with browser rendering so the other colors don't get rendered.
Try the setTimeout() function with a different offset for each color

This version does not deal with "setTimeout" and "setInterval"
var bgs = ['red', 'blue', 'yellow', 'green', 'black'];
function *getBgs(){
for(let v of bgs) {
yield v;
}
}
$('button').click(function() {
let iter = getBgs();
let $div = $('div');
var delay = 150;
var prev = 0;
(function nextColor(){
requestAnimationFrame(function(t){
if(prev && t - prev < delay) {
return nextColor();
}
prev = t;
let next = iter.next();
if(next.done) return;
$div.css('background-color', next.value);
nextColor();
});
})();
});
div {
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>
Go
</button>

Related

how to change border color on click

I want to change colors in a random order when I click with that colors "red", "hotpink", "greenyellow", "tomato", "lightcoral", "lightblue":
function changeColor() {
document.getElementById("box").style.borderColor=red", "hotpink", "greenyellow ", "tomato", "lightcoral", "lightblue"
All the other answers here seem to be generating a random index so the generated color is always random.
To change the color in a random order, shuffle the array of colors using the Fisher-Yates (aka Knuth) Shuffle and use a variable to keep track of the index.
var colors = shuffle(["red", "hotpink", "greenyellow ", "tomato", "lightcoral", "lightblue"]);
var i = 0;
function changeColor() {
document.getElementById("box").style.borderColor = colors[i];
if (colors.length - 1 == i) {
i = 0;
} else {
i++;
}
}
function shuffle(r){for(var f,n=r.length;0!==n;)f=Math.floor(Math.random()*n),n--,[r[n],r[f]]=[r[f],r[n]];return r}
#box {
height: 50px;
width: 50px;
border: 10px solid;
}
<div id="box">
</div>
<button onclick="changeColor()">Change</button>
You can JavaScript Math.random() function.
function changeColor(){
var colors = ['red', 'green', 'blue', 'orange', 'yellow'];
document.getElementById("box").style.borderColor = colors[Math.floor(Math.random() * colors.length)];
}
#box{
border: 1px solid black;
height:100px;
margin: 0 auto;
}
#box:hover{
cursor:pointer
}
<div id="box" onclick="changeColor();">
<div>
const div = document.getElementById("a");
const colorArr = ["red", "green", "blue", "orange", "yellow"];
function changeColor() {
// grab a color from the array ;
// step one grab a random index from the array or colorArr
let index = Math.floor(Math.random() * (colorArr.length + 1));
// console.log(index);
div.style.borderColor = colorArr[index]
}
function changeColor2() {
const randomColor = Math.floor(Math.random()*16777215).toString(16);
div.style.borderColor = "#" + randomColor
// https://www.w3schools.com/jsref/jsref_tostring_number.asp
}
#a{
border: 25px solid red;
width: 235px;
height: 235px;
display: flex;
background-color: "black"
}
<div id="a"> </div>
<button onclick = "changeColor()"> Click me </button>
<button onclick = "changeColor2()"> More Random Colors </button>
let colors = ["red", "hotpink", "greenyellow ", "tomato", "lightcoral", "lightblue"];
function changeColor() {
document.getElementById("box").style.borderColor=colors[Math.floor(Math.random()*colors.length)];
}
I recommend that put color in array and generate a random number between 0-4 and fetch that array element .

Looping through array of colors infinite amount of times

I have a button with a default background color(black). I want to change the background color (from an array) of this button when hovering over it. I have it working at a fundamental level, but I want it to repeat the loop over and over.
this is what i have so far.
var color = ['#3e50a2', '#faa51a', '#ed1c24', '#2a9446'];
var i = -1;
document.querySelector('.customBtn').addEventListener('mouseover', function() {
i = 1 < color.length ? ++i : 0;
document.querySelector('.customBtn').style.background = color[i]
});
document.querySelector('.customBtn').addEventListener('mouseout', function() {
document.querySelector('.customBtn').style.background = '#000';
})
<a class="customBtn">Button</a>
I think you tried to reset the value of i with this i = 1 < color.length ? ++i : 0; but it doesn't. This will continuously increase the value never resetting it because 1 is always less than the length of the array.
I think you meant to increment the value and then reset if it's too big:
i = ++i < color.length ? i : 0;
Here's the complete code. I've refactored the query selector as there's no point to doing it more than once, and changed the mouseout background colour so you can read the button
var color = ['#3e50a2', '#faa51a', '#ed1c24', '#2a9446'];
var i = -1,
btn = document.querySelector('.customBtn');
btn.addEventListener('mouseover', function() {
i = ++i < color.length ? i : 0;
btn.style.background = color[i];
});
btn.addEventListener('mouseout', function() {
// revert to default colour
btn.style.background = '';
})
<input type="button" class="customBtn" value="My button" />
Just replace i = 1 < color.length ? ++i : 0; with i = (i+1 < color.length) ? ++i : 0;. That's all.
var color = ['#3e50a2', '#faa51a', '#ed1c24', '#2a9446'];
var i = -1;
document.querySelector('.customBtn').addEventListener('mouseover', function() {
i = (i+1 < color.length) ? ++i : 0;
document.querySelector('.customBtn').style.background = color[i]
});
document.querySelector('.customBtn').addEventListener('mouseout', function() {
document.querySelector('.customBtn').style.background = '#000';
})
<a class="customBtn">Button</a>
If you must use javascript, take a look at the second example.
Pure CSS solution
You could accomplish this with a CSS animation, which would be both more efficient and less error prone. Unless there's a specific reason you need to use javascript here I'd strongly recommend this approach.
This example could be modified to do hard transitions instead of fading from one color to the next, but here's a quick demo:
button {
background: black;
color: white;
border: none;
padding: 0.5em 1em;
}
button:hover {
animation: buttonhover 1s infinite;
}
#keyframes buttonhover {
0% {
background: #3e50a2;
}
25% {
background: #faa51a;
}
50% {
background: #ed1c24;
}
75% {
background: #2a9446;
}
}
<button>Hello</button>
Javascript Solution
If you must use javascript for whatever reason, you can use the % operator to keep from running off the end of the colors array:
const colors = ['#3e50a2', '#faa51a', '#ed1c24', '#2a9446'];
let index = 0;
let interval;
const hover = (e) => {
interval = setInterval(() => {
e.target.style.backgroundColor = colors[index];
index = (index + 1) % colors.length;
}, 300);
}
document.querySelector('button').addEventListener('mouseover', hover);
document.querySelector('button').addEventListener('mouseout', (e) => {
clearInterval(interval);
e.target.style.backgroundColor = 'black';
});
button {
background: black;
color: white;
border: none;
padding: 0.5em 1em;
}
<button>Hello</button>

how to create an automatic traffic light sequence in javascript

Hi I'm relatively new to JavaScript and I'm attempting to create a traffic light sequence that runs automatically, the code I currently have only works on click, if anyone can help me make this automatic, that'd be great.
<!DOCTYPE html>
<html>
<body>
<img id="Change Lights" src="red.gif" width="36" height="98">
<br><button onclick="nxt()" id="button">Change colour</button></br>
<script>
var img = new Array("red.gif","redamber.gif","green.gif","yellow.gif");
var imgElement = document.getElementById("Change Lights");
var lights = 0;
var imgLen = img.length;
function nxt()
{
if(lights < imgLen-1)
{
lights++;
}
else{
lights=0;
}
imgElement.src = img[lights];
}
</script>
</body>
</html>
A similar question was posted yesterday, but I thought I'd chip in with an answer here.
JavaScript
var timeIndex = 0;
var lightIndex = 0;
var timer;
var trafficLight = document.getElementById('light');
var lights = [
{
duration: 5,
color: 'red',
image: 'red.gif'
},
{
duration: 4,
color: 'green',
image: 'green.gif'
},
{
duration: 1,
color: 'yellow',
image: 'yellow.gif'
}
]
function advanceTrafficLightTimer() {
timeIndex++;
if(timeIndex == lights[lightIndex].duration) {
timeIndex = 0;
lightIndex = lightIndex < lights.length - 1 ? lightIndex = lightIndex + 1 : 0;
trafficLight.src = lights[lightIndex].image;
trafficLight.className = lights[lightIndex].color;
}
}
timer = setInterval(advanceTrafficLightTimer,1000);
CSS
.red { border: 3px solid #f00; }
.green { border: 3px solid #0f0; }
.yellow { border: 3px solid #ff0; }
HTML
<img id="light" class="red" src="red.gif">
The JS works by updating the timeIndex every second, and checking a variable lightIndex against the available traffic light objects stored in the array trafficLight. If the timeIndex has reached the duration of the current trafficLight, it will update the lightIndex to the next object in the array and change the image.
You can see it working here: https://jsfiddle.net/igor_9000/a2w9g8qa/3/
This seems to be a homework problem (nothing wrong with posting questions about homework). I've left out the redamber color, hopefully adding that in gives you a little bit of practice with the homework.
Hope that helps!

Pause or Delay a loop on a array in a setInterval()

I want the color of the box I have created to change every 0.5 seconds, I have stored the colors in an array and I want the color to change every .5 seconds but it changes all at once.
<style type="text/css">
#box{
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript">
var colors = ['red','blue','green','violet','purple'];
var box = document.getElementById('box');
setInterval(function(){
for(var i=0; i < colors.length; i++){
box.style.backgroundColor=colors[i];
}
}, 300);
</script>
Depending on whether you want the box to continue changing after it has been through all the colours, there are a number of ways to solve this:
/*
Keeps running
*/
var colors = ['red','blue','green','violet','purple'],
i = 0;
setInterval(function () {
box.style.backgroundColor = colors[i++ % colors.length];
}, 500);
/*
Runs once only
*/
var colorsOnce = colors.slice(),
interval = setInterval(function () {
once.style.backgroundColor = colorsOnce.shift();
if(!colorsOnce.length) clearInterval(interval);
}, 500);
.box{
width: 100px;
height: 100px;
background: green;
}
<div id="box" class="box"></div>
<div id="once" class="box"></div>
Note: Despite these examples, where timing functions are involved best practice is generally to use a timeout as described by #AmmarCSE above.
You are looping inside the interval callback, which means that it will go through all the colors each interval.
Make the interval be the loop instead, i.e. go one step furter for each interval. Example:
var index = 0;
setInterval(function(){
box.style.backgroundColor = colors[index];
index = (index + 1) % colors.length;
},300);
Demo:
var colors = ['red','blue','green','violet','purple'];
var box = document.getElementById('box');
var index = 0;
setInterval(function(){
box.style.backgroundColor = colors[index];
index = (index + 1) % colors.length;
},300);
#box{
width: 100px;
height: 100px;
background: green;
}
<div id="box"></div>
Note: To actually get an interval that runs every 0.5 seconds, you should use 500 instead of 300 in the setInterval call.
Use setTimeout()
var colors = ['red', 'blue', 'green', 'violet', 'purple'];
var box = document.getElementById('box');
for (var i = 0; i < colors.length; i++) {
(function(index) {
setTimeout(function() {
console.log(index);
box.style.backgroundColor = colors[index];
}, 300 * i);
})(i)
}
#box {
width: 100px;
height: 100px;
background: green;
}
<div id="box"></div>
Two key points you missed in your code
Half a second is "500 milliseconds". So you need to change from 300 ms to 500ms in setInteval.
When the timer kicks in, you need to update the background color with the "next color in the array".
So you may try something like:
var color = 0;
var colors = ['red','blue','green','violet','purple'];
function nextColor(){
color ++;
if (color>=colors.length)
color = 0;
return colors[color];
}
setInterval(function(){
box.style.backgroundColor = nextColor();
},500);
This will keep the box changes its color every half a second and cycle through the color array endlessly.

how to target click event in javascript

How can I target the click event so that I can reuse the .js-box in different divs without effecting the other div containers?
var box = document.querySelector('.js-box'),
colors = ['green', 'blue', 'red'];
box.onclick = function() {
color = colors.shift();
colors.push(color);
box.className = 'js-box' + ' ' + color;
};
I'm quite sure my solution is to do with the correct use of 'this' but i can seem to get my head around it
http://jsfiddle.net/Grundizer/ky1tb3r5/
document.querySelector only selects the first element, not all!
Thats why you need document.getElementsByClassName
var boxes = document.getElementsByClassName('js-box'),
colors = ['green', 'blue', 'red'];
for (var i = 0; i < boxes.length; i++)
{
boxes[i].onclick = function() {
color = colors.shift();
colors.push(color);
this.className = 'js-box' + ' ' + color;
};
}
.js-box {
width:200px;
height:200px;
margin:50px;
border:thin grey solid;
display:block;
}
.red {
background-color:red;
}
.blue {
background-color:blue;
}
.green {
background-color:green;
}
<div class="js-box"></div>
<div class="js-box"></div>

Categories

Resources