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>
Related
I have made 30 buttons in JavaScript now I want all buttons to be green like the first button and whenever you click on a button it turns and stays red.
For some reason only the first button is green and whenever I click it it won't turn red. I tried using: button.style.backgroundColor = "red"; in a function to make the button red when clicked but this doesn't work
const color = ["green"];
page();
function onbuttonclicked() {
document.body.style.backgroundColor = color[nr - 1];
}
function page() {
document.body.style.backgroundColor = "grey";
//style page
createButtons(30);
}
function set_onclick(amount) {
for (var a = 1; a < (amount + 1); a++) {
document.getElementById("button" + a).setAttribute("onclick", "onbuttonclicked(" + a + ")");
}
}
function createButtons(amount) {
for (var a = 1; a < (amount + 1); a++) {
var button = document.createElement("button");
button.style.backgroundColor = color[a - 1];
button.id = "button" + a;
button.innerHTML = "button " + a;
container.appendChild(button);
}
set_onclick(amount);
}
<div id="container"></div>
EDIT
thanks for all the answers it isnt possible to only change certain buttons when you click on them right? so when i click on button1 nothing happens but whenever i click on button 3 it turn red
You need to pass nr as a parameter in onbuttonclicked function
EDIT:
OP Comment:
okay so i need to add an parameter. but i want all 30 buttons to be green so when you open the page all buttons are green this also has to do with the parameter?
For that in your loop createButton, change color[a - 1] for color[0]
const color = ["green"];
function onbuttonclicked(nr) {
document.body.style.backgroundColor = color[nr - 1];
}
function page() {
//style page
document.body.style.backgroundColor = "grey";
createButtons(30);
}
function set_onclick(amount, nr) {
for (let a = 1; a < (amount + 1); a++) {
document.getElementById(`button${a}`).setAttribute("onclick", `onbuttonclicked(${nr})`);
}
}
function createButtons(amount) {
for (let a = 1; a < (amount + 1); a++) {
const button = document.createElement("button");
button.style.backgroundColor = color[0];
button.id = `button${a}`;
button.innerHTML = `button ${a}`;
container.appendChild(button);
}
set_onclick(amount, 1);
}
page();
<div id="container"></div>
const number_of_buttons = 30;
createButtons();
function createButtons(){
var container = document.getElementById("container");
for(var i=1;i<=number_of_buttons;i++){
var button = document.createElement("button");
button.innerText = "Button " + i;
button.style.backgroundColor = "green";
button.onclick = function(event){
var source = event.target || event.srcElementl
source.style.backgroundColor = "red";
};
container.appendChild(button);
}
}
button{
margin: 10px;
font-family: 'Consolas';
font-size: 20px;
padding: 5px;
outline: none;
cursor: pointer;
transition: 0.5s;
}
button:hover{
border: 1px solid black;
}
button:active{
transform: translateY(2px);
}
<div id="container">
</div>
This is what you have asked for!
I did the styling for better looks!
This line: button.style.backgroundColor = color[a - 1]; is wrong, since your color array only contains a single string ("green"). You should do color[0], or, you need to populate the array to have 30 elements.
document.body.style.backgroundColor = color[nr - 1]; - Where is this nr variable came from? The correct line should be button.style.backgroundColor = "red"; or - again - you can populate the color (i.e const color=["green", "red"]) and use color[1].
Check out this demo
A common way to do this is to use CSS classes:
page();
function onbuttonclicked(a) {
//document.body.style.backgroundColor = color[nr - 1];
document.getElementById("button" + a).classList.remove("button")
document.getElementById("button" + a).classList.add("clickedbutton")
}
function set_onclick(amount) {
for (var a = 1; a < (amount + 1); a++) {
document.getElementById("button" + a).setAttribute("onclick", "onbuttonclicked(" + a + ")");
}
}
function page() {
document.body.style.backgroundColor = "grey";
//style page
createButtons(30);
}
function createButtons(amount){
for (var a = 1;a <(amount + 1); a++) {
var button = document.createElement("button");
button.classList.add("button")
button.id = "button" + a;
button.innerHTML = "button " + a;
container.appendChild(button);
}
set_onclick(amount);
}
.clickedbutton {
background-color: red;
}
.button {
background-color: green;
}
<div id="container"></div>
I have a time variable that updates and want to restart its value only when you mouse over on a different element, if you hover on the same element it should keep updating. How should I approach this? Here's part of the code:
// Change shaders
function changeShader() {
const elements = document.querySelectorAll('.caption');
elements.forEach(element => {
element.addEventListener('mouseover', function() {
if (you hovered on the same element) {
console.log('you moused over the same element');
} else {
console.log('you moused over on a different element');
}
});
});
}
You can save last hovered dom and check if it's the same:
function changeShader() {
let last_hover;
const elements = document.querySelectorAll('.caption');
elements.forEach(element => {
element.addEventListener('mouseover', function() {
if (last_hover == this) {
console.log('you moused over the same element');
} else {
console.log('you moused over on a different element');
}
last_hover = this;
});
});
}
changeShader()
.caption, .no-hover{
padding:10px;
margin-bottom: 25px;
background-color: #ccc;
cursor: pointer;
}
<div class="caption">I am Caption 1</div>
<div class="caption">I am Caption 2</div>
<div class="caption">I am Caption 3</div>
<div class="caption">I am Caption 4</div>
<div class="caption">I am Caption 5</div>
This is one way to do so dynamically with JavaScript. In this example, the code assigns a handler to the onmouseover event of each element, in this case each element is a button.
var flags = new Array(2);
flags[0] = 0;
flags[1] = 0;
var buttons = document.getElementsByTagName("button");
for (let i = 0, max = buttons.length; i < max; i++) {
let temp = i;
buttons[temp].onmouseover= function(){
console.log("Moused over this button " + buttons[temp].id + " " + flags[temp]++ + "x before." );
if ((flags[temp] == 2)) {
this.onmouseover = null;
alert("Done documenting bbutton " + buttons[temp].id);
}
};
}// end for
<style>
#a {
background: #000;
color: lime;
}
#b {
background: #000;
color: cyan;
}
#a:hover,#b:hover {
background: #600;
color: #ffdede;
}
</style>
<div><button id="a">Button A</button>
<button id="b">Button B</button></div>
By setting each button with a unique id attribute, it uses that value to distinguish which button is being moused over.
Note: the CSS is strictly optional -- just wanted to enhance the visuals.
I am trying to make my selector so when it gets the class of transform with the tagname with p, it will do some event in my case it is mouse hovering but i am having trouble with it.
I know there are jquery solutions but i am doing it with pure javascript. here is the code below currently
var hoverEvent = document.getElementsByTagName("p").getElementsByClassName("transform");
for (let i = 0; i < hoverEvent .length; i++) {
hoverEvent [i].onmouseover=function() {
this.style.color = "yellow";
// changes paragraph with class of transform to yellow during hover
}
} // end for
for (let i = 0; i < hoverEvent .length; i++) {
hoverEvent [i].onmouseout=function() {
this.style.color = "black";
// changes it back to black
}
}
You can use a CSS selector in querySelectorAll to find all paragraphs with that classname:
var hoverEvent = document.querySelectorAll("p.transform");
var transformPs = document.querySelectorAll("p.transform");
for (let i = 0; i < transformPs .length; i++) {
// on mouse over
transformPs[i].onmouseover = function () {
this.style.color = "yellow";
// changes paragraph with class of transform to yellow during hover
};
// on mouse out
transformPs[i].onmouseout = function () {
this.style.color = "black";
// changes it back to black
};
}
you can use classList to check class of element
var p = document.getElementsByTagName("p");
if (p.classList.contains('transform')){
// do whatever you want to do
}
The vanilla JavaScript equivalent would be using document.querySelectorAll:
function turnYellow (e) { e.target.style.color = 'yellow' }
function turnBlack (e) { e.target.style.color = '' }
document.querySelectorAll('p.transform').forEach(function (p) {
p.addEventListener('mouseover', turnYellow)
p.addEventListener('mouseout', turnBlack)
})
body { background: #ccc; }
<p class="transform">Example Paragraph</p>
However, I think the best approach would be to forego the JavaScript altogether and instead rely on the CSS pseudo-selector :hover:
body { background: #ccc; }
p.transform:hover {
color: yellow;
}
<p class="transform">Example Paragraph</p>
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>
How can you randomize hover effects?
For example:
<p>test</p>
p:hover {
background: yellow;
}
p:hover:
background: red;
}
Please note that the above is for-example only. The question is, how can you randomize hover effects, so it shows the background:yellow; and background:red; once in random order on the onmouseover?
There should not be any order, like for example: on first hover - one class is added, on second - another. It should be completely random.
Use the following function to get random colors and use mouseover event to change the background color.
function getRandomColor () {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
})
$( "p" ).mouseover(function() {
$(this).css("background",getRandomColor());
});
Please check this Fiddle.
You could add a random class to the element on hover and remove it when the hover event is done.
If you have the following CSS:
.yellow {
background: yellow;
}
.red {
background: red;
}
You could use the follow jQuery code example:
// Declare all classes that can be used in the random selection
var classes = ['yellow', 'red'];
$("p").hover(
function() {
// Select a random class
var randomClass = classes[Math.floor(Math.random() * classes.length)];
$(this).addClass(randomClass);
}, function() {
$(this).removeClass();
}
);
You can check an example on this Fiddle.
The random selection is made on the classes array using the Math.random() function.
$(document).ready(function(){
$("p[data-random]").mouseover(function(){
max_value=5;
random_value= Math.floor((Math.random() * max_value) + 1);
$(this).attr("data-random",random_value);
});
})
p[data-random]{
padding: 10px;
border:1px solid black;
}
p[data-random]:hover {
cursor: pointer
}
p[data-random="1"]:hover {
background: yellow;
}
p[data-random="2"]:hover {
background: red;
}
p[data-random="3"]:hover {
background: black;
}
p[data-random="4"]:hover {
background: white;
}
p[data-random="5"]:hover {
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p data-random="1">Hello</p>
This is best way to do random effect on background, here I have considered 5 colors for random effect.
You should play with setting different classes using javascript.
For example something like that (jquery) :
var randomClasses = ['class1','class2','class3'];
$('p').mouseover(function(){
$(this).toggleClass(function() {
var randomColor = randomClasses[getRandomInt(0,randomClasses.length-1)];
return randomColor;
});
})
function getRandomInt(min, max)
{
return Math.floor(Math.random() * (max - min + 1)) + min;
}