How to create an event button - javascript

I am currently working on a project. Basically, there is a big grid square and inside of it, there are lots of little squares. When users move their mouse over these little squares they turn into black. However, I want to create a clear button that turns the color of these squares into their original color. I have a code but it doesn't work. I can turn their color into black but I cannot create an event button which clears everything.
Alter the code, tried different methods.
//set values
let tiles = document.getElementsByClassName('newDiv');
let buttons = document.getElementsById('clearbutton');
//make squares black using mouseover event
if(black){
for (const tile of tiles) {
tile.addEventListener('mouseover', e => {
tile.style.backgroundColor = "black";
});
}
}
//turn squares background-color into their original color
for (const cbutton of clearbutton) {
button.addEventListener('click', e => {
tiles.style.backgroundColor = "#eee";
});
}
<nav id="navbar">
<ul>
<li><button id = "clearbutton" type="button" style= "width: 200px; height; 150px; background-color: #99CCFF;">Clear</button></li>
</ul>
</nav>
<div id="container">
</div>
getElementById is not a function.

Use the code below
let tiles = document.getElementsByClassName('newDiv');
let clearbutton = document.getElementById('clearbutton');
if (black) {
for (const tile of tiles) {
tile.addEventListener('mouseover', e => {
tile.style.backgroundColor = "black";
});
}
}
clearbutton.addEventListener('click', e => {
for (const tile of tiles) {
tile.style.backgroundColor = "#eee";
}
});
Here is a full working example
var black = true;
let tiles = document.getElementsByClassName('newDiv');
let clearbutton = document.getElementById('clearbutton');
if (black) {
for (const tile of tiles) {
tile.addEventListener('mouseover', e => {
tile.style.backgroundColor = "black";
});
}
}
clearbutton.addEventListener('click', e => {
for (const tile of tiles) {
tile.style.backgroundColor = "#eee";
}
});
.newDiv {
width: 100px;
height: 100px;
display: inline-block;
background: #eeeeee;
}
<button id="clearbutton">Clear All</button>
<div id="container">
<div class="newDiv"></div>
<div class="newDiv"></div>
<div class="newDiv"></div>
<div class="newDiv"></div>
<div class="newDiv"></div>
<div class="newDiv"></div>
<div class="newDiv"></div>
</div>

Related

How to save new background color via `colorpicker` to `localStorage`?

I know there's a lot of similar questions.. I've tried them but I really can't incorporate it to my project.
I'm trying to save to localStorage the new background-color selected using the native colorpicker.
I'm almost there but I just can't figure out how to make it work.
Please see my code so far:
function changeBgColor(color) {
if (color) window.localStorage.setItem('bgColor', color);
else if (!(color = window.localStorage.getItem('bgColor'))) return;
document.getElementById('colorpicker').addEventListener('input', function() {
var elements = document.getElementsByClassName("card-bg")
for (var i = 0; i < elements.length; i++) {
elements[i].style.background = this.value;
}
})
}
window.addEventListener('DOMContentLoaded', () => changeBgColor());
.card1 {
width: 200px;
height: 200px;
background-color: #222;
margin: 10px 0 0 0;
}
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<br>
<input type="color" id="colorpicker" onselect="changeBgColor();">
The important feature for me are:
To change background color using input="color"
Use class selector since I have multiple divs I want to target with the same input
Save the value to localStorage
That's all really. I just need to figure out the part where the value gets saved to localStorage.
After I make this work, I will need to replicate it for a different set of divs..
Thank you in advance for any help.
If check had = assignment instead of == comparison
Here is a working refactored snippet:
let pretend_local_storage = null
function setupBackgroundColorChange() {
const elements = document.querySelectorAll(".card-bg")
document.getElementById('colorpicker').addEventListener('input', function(e) {
color = e.target.value
if (color === pretend_local_storage) return
pretend_local_storage = color
elements.forEach((element) => element.style.background = color)
})
}
window.onDOMContentLoaded = setupBackgroundColorChange();
.card1 {
width: 200px;
height: 200px;
background-color: #222;
margin: 10px 0 0 0;
}
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<br>
<input type="color" id="colorpicker" onselect="changeBgColor();">
Local Storage example:
localStorage.getItem('bgColor', null)
function setupBackgroundColorChange() {
const elements = document.querySelectorAll(".card-bg")
setColor(elements, localStorage.getItem('bgColor', '#000'))
document.getElementById('colorpicker').addEventListener('input', function (e) {
color = e.target.value
if (color === localStorage.getItem('bgColor')) return
localStorage.setItem('bgColor', color)
setColor(elements, color)
})
}
function setColor(elements, color) {
elements.forEach((element) => element.style.background = color)
}
window.onDOMContentLoaded = setupBackgroundColorChange();
First of all i would use onchange trigger. To be honest, you dont need any condition inside the function. you can set the color to localStorage and that is it.
/* this lines check if already set color to localStorage */
if (window.localStorage.getItem('bgColor')) {
var elements = document.getElementsByClassName("card-bg")
for (var i = 0; i < elements.length; i++) {
elements[i].style.background = this.value;
}
}
function changeBgColor() {
let color = document.getElementById('colorpicker').value;
const bg_curr = localStorage.getItem('bgColor');
console.log(color, bg_curr);
localStorage.setItem('bgColor', color);
document.getElementById('colorpicker').addEventListener('input', function() {
var elements = document.getElementsByClassName("card-bg")
for (var i = 0; i < elements.length; i++) {
elements[i].style.background = color;
}
})
}
window.addEventListener('DOMContentLoaded', () => changeBgColor());
.card1 {
width: 200px;
height: 200px;
background-color: #222;
margin: 10px 0 0 0;
}
<input type="color" id="colorpicker" onchange="changeBgColor();">
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<div class="card1 card-bg">Set A</div>
<br>

Change color of current element and remove background from previous click

So I have a list of elements that originally have white backgrounds and my goal is when I click one of it it changes color to blue, but only one element can by chosen and have color - if another element was clicked earlier it background return to white
I was trying with this code but it doesn't work
var prevDiv=null
function change_color_to_blue_click(){
if(prevDiv) {
prevDiv.style.backgroundColor = "white";
}
var target = event.currentTarget
target.style.backgroundColor="blue"
selected = true
prevDiv = target;
}
The only thing I can think of is that you didn't pass event into the function.
Was there a reason why you didn't accept an event argument in your function? (Maybe because Internet explorer used to use a global event object.)
This worked for me:
function change_color_to_blue_click(event){
if(prevDiv) {
prevDiv.style.backgroundColor = "white";
}
var target = event.currentTarget
target.style.backgroundColor="blue"
selected = true
prevDiv = target;
}
var prevDiv=null
function changeColor(){
if(prevDiv) {
prevDiv.style.backgroundColor = "white";
}
var target = event.currentTarget
target.style.backgroundColor="blue"
selected = true
prevDiv = target;
}
.box {
width: 50px;
height: 50px;
border: solid black 2px;
margin: 20px;
display: inline-block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="click">
<div onclick="changeColor()" class="box"></div>
<div onclick="changeColor()" class="box"></div>
<div onclick="changeColor()" class="box"></div>
<div onclick="changeColor()" class="box"></div>
</div>
</body>
</html>
var prevDiv = null;
function changeColor() {
var target = event.currentTarget;
if (prevDiv) {
prevDiv.style.backgroundColor = "white";
target.style.backgroundColor = "blue";
prevDiv = target;
} else {
target.style.backgroundColor = "blue";
prevDiv = target;
}
}

Make all selected css circles active

I am trying to create a progress bar of css circles, in which after clicking on every circle like 1, 2, 3 all the three circles and their connected line will be filled by red color and if go back like 3, 2, 1 then color should be removed.
HTML :
<div class="row well" id="rows">
<ul id="progressbar" class="progressbar">
<li class="cir danger">THOUGHFUL</li>
<li class="cir">PASSION</li>
<li class="cir">POWER OF DESIGN</li>
<li class="cir">BUILDING RELATIONSHIPS</li>
<li class="cir">ENHANCE HUMAN INTERATION</li>
</ul>
</div>
JS :
var header = document.getElementById("rows");
var bar = document.getElementsByClassName("progressbar");
var btns = header.getElementsByClassName("cir");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function () {
var danger = document.getElementsByClassName("danger");
danger[0].className = danger[0].className.replace("danger", "");
this.className += " danger";
});
}
Sample Img:
Referring to above imag, if i click on circle 3 then circle 1,2,3 should be in red color and then if i click circle 2 then circle 3 should be white and 1 & 2 should be red, vice versa.
I have tried to achieve it by JS but classnotfound error .
Any help for this would be appreciated.
Every time a circle is clicked, grab its data-id and activate all circles of an equal or lesser data-id.
let circles = document.querySelectorAll(".circle")
circles.forEach(el => {
el.addEventListener("click", (e) => {
let id = e.target.dataset.id
circles.forEach(el2 => {
if(el2.dataset.id <= id){
el2.classList.add("active")
}else{
el2.classList.remove("active")
}
})
})
})
.circled{display:flex}
.circle{
border-radius:50%;
width:50px;
height:50px;
border: solid 2px #333;
display:inline-flex;
align-items:center;
justify-content:center;
position:relative;
margin-left: 44px;
cursor:pointer;
}
.circle:not(:first-of-type)::before{
height: 2px;
width: 50px;
content:"";
background-color: #333;
position:absolute;
left:-50px;
}
.circle.active{
border-color: #f00;
}
.circle.active:not(:first-of-type)::before{
background-color: #f00;
}
<div class="circles">
<div class="circle active" data-id="1">1</div>
<div class="circle" data-id="2">2</div>
<div class="circle" data-id="3">3</div>
<div class="circle" data-id="4">4</div>
<div class="circle" data-id="5">5</div>
</div>
Not proud of this
var header = document.getElementById("rows");
var bar = document.getElementsByClassName("progressbar");
var btns = header.getElementsByClassName("cir");
Array.prototype.forEach.call(btns,function(btn){
btn.addEventListener('click', function(e){
updateProgress(btn,e)
})
});
function updateProgress(btn,e){
removeDangerFromAll();
for( let btnToCheck of btns){
btnToCheck.classList.add('danger');
if (btnToCheck == btn) {
break;
}
}
}
function removeDangerFromAll(){
Array.prototype.forEach.call(btns,function(btn){
btn.classList.remove('danger');
});
}
UPDATE: Switched to cleaner classList as Other Answer

Can I reversing these buttons easier on myself?

So, I'm wondering if i can make this any simpler (less repetition in the javascript) and whether or not I can make it so the title only turns black when hitting a button if it is that buttons color. If the second part of the question is possible it doesn't need to be simpler I'm just trying to figure out how to make the function target only tags with a specific attribute (style). Is this possible?
I'm new to coding I've been trying to figure this out for a few hours and can't find something already uploaded... possibly due to my lack of being able to condense the question.
<!DOCTYPE html>
<html>
<head>
<title>
Flood
</title>
<link rel="stylesheet" href="Style.css">
<style>
h1 {
text-align: center;
padding-left: 30%;
padding-right: 30%;
width: 40%;
}
p {
font-size: 14pt
}
</style>
</head>
<body>
<section class="mainpage">
<h1 id="FS"> Fun Stuff </h1>
<div>
<button id="Red"> Red</button>
<button id="Blue"> Blue</button>
<button id="Yellow"> Yellow</button>
<button id="Blink"> Blink</button>
</div>
<div id="explaination">
<p>Click the buttons at the top to see what I mean.
</p>
</div>
</section>
<script>
const a = document.getElementById("FS");
const b = document.getElementById("Red");
const c = document.getElementById("Blue");
const d = document.getElementById("Yellow");
const e = document.getElementById("Blink");
/*reset Functions*/
function blackFunctionB() {
a.style.color = "black";
b.removeEventListener("click", blackFunctionB,);
b.addEventListener("click", redFunction,);
}
function blackFunctionC() {
a.style.color = "black";
c.removeEventListener("click", blackFunctionC,);
c.addEventListener("click", blueFunction,);
}
function blackFunctionD() {
a.style.color = "black";
d.removeEventListener("click", blackFunctionD,);
d.addEventListener("click", yellowFunction,);
}
function showFunction() {
a.style.display = "block";
e.removeEventListener("click", showFunction,);
e.addEventListener("click", blinkFunction,)
}
/*end reset functions*/
b.addEventListener("click", redFunction,);
function redFunction() {
a.style.color = "Red";
b.removeEventListener("click", redFunction,);
b.addEventListener("click", blackFunctionB,);
}
c.addEventListener("click", blueFunction,);
function blueFunction() {
a.style.color = "Blue";
c.removeEventListener("click", blueFunction,);
c.addEventListener("click", blackFunctionC,);
}
d.addEventListener("click", yellowFunction,);
function yellowFunction() {
a.style.color = "Yellow";
d.removeEventListener("click", yellowFunction,);
d.addEventListener("click", blackFunctionD,);
}
e.addEventListener("click", blinkFunction,);
function blinkFunction() {
a.style.display = "none"
e.removeEventListener("click", blinkFunction,);
e.addEventListener("click", showFunction,);
}
</script>
</body>
So basically when you click on the yellow button it makes the block turn yellow, then if you hit the blue button it makes it blue, but if you hit the yellow button again it makes it black. Alternatively, when you hit the yellow then blue twice then yellow again it stays black. Is there a way to make it only turn black if you hit the yellow button when it is already yellow?
You could make one function that is more generic and can handle all the cases you have:
function toggleCss(elem, attrib, value) {
elem.style[attrib] = elem.style[attrib] === value ? "" : value;
}
const fs = document.getElementById("FS");
for (let color of ["red", "blue", "yellow"]) {
const button = document.getElementById(color);
button.addEventListener("click", () => toggleCss(fs, "color", color));
}
const button = document.getElementById("blink");
button.addEventListener("click", () => toggleCss(fs, "visibility", "hidden"));
<section class="mainpage">
<h1 id="FS"> Fun Stuff </h1>
<div>
<button id="red"> Red </button>
<button id="blue"> Blue </button>
<button id="yellow"> Yellow </button>
<button id="blink"> Blink </button>
</div>
<div id="explanation">
<p>Click the buttons at the top to see what I mean.</p>
</div>
</section>
You could even make it more generic by defining data attributes on the buttons which indicate which CSS property needs to toggle:
function toggleCss(elem, attrib, value) {
elem.style[attrib] = elem.style[attrib] === value ? "" : value;
}
const fs = document.getElementById("FS");
for (const button of document.querySelectorAll("button[data-attr]")) {
button.addEventListener("click", () =>
toggleCss(fs, button.dataset.attr, button.dataset.value)
);
}
<section class="mainpage">
<h1 id="FS"> Fun Stuff </h1>
<div>
<button data-attr="color" data-value="red">Red</button>
<button data-attr="color" data-value="blue">Blue</button>
<button data-attr="color" data-value="yellow">Yellow</button>
<button data-attr="visibility" data-value="hidden">Blink</button>
</div>
<div id="explanation">
<p>Click the buttons at the top to see what I mean.</p>
</div>
</section>
You are over complicating things. Simply check and toggle the black and 2nd color.
You don't have to register/de-register events again and again.
function yellowFunction() {
var clr = a.style.color;
if(clr.toLowerCase() === 'yellow')
a.style.color = "black";
else
a.style.color = "Yellow";
}

Highlight the text in textarea with delay

I am trying to highlight the single line of text in <textarea> with time delay. And I am wondering if I can choose a different color? The thing I wanted is when I click on the first <button>, the first line is highlighted into blue, click on the second <button>, 1 second later, the second line is highlighted into blue, lastly click on the third <button>, 2 second later, the third line is highlighted into yellow. I noticed I have a bug that I clicked on the button 3 times then the highlight doesn't work, but it is okay for me, I just want to know how to make the time delay and highlight with a different color. Thank you very much.
$( document ).ready(function() {
var str = 'line 1\nline 2\nline 3\n';
var textNumChar = str.length;
$('#str').val(str);
startPosition = 0;
$(".lines").click(function() {
var tarea = document.getElementById('str');
for(i=startPosition;i<textNumChar;i++)
{
if(str[i]=='\n') {
endposition = i;
break;
}
}
tarea.selectionStart = startPosition;
tarea.selectionEnd = endposition;
startPosition = endposition+1;
});
});
#container {
float: left;
}
button {
width: 50px;height: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="container">
<button class="lines" id="line1">line 1</button>
<br>
<button class="lines" id="line2">line 2</button>
<br>
<button class="lines" id="line3">line 3</button>
</div>
<textarea id="str" rows="6"></textarea>
You can use setTimeout() to set the delay in highlighting the text based on button id.
And ::selection css selector to style the portion of an element that is selected.
$( document ).ready(function() {
var str = 'line 1\nline 2\nline 3\n';
var textNumChar = str.length;
$('#str').val(str);
startPosition = 0;
$(".lines").click(function(e) {
var tarea = document.getElementById('str');
for(i=startPosition;i<textNumChar;i++)
{
if(str[i]=='\n') {
endposition = i;
break;
}
}
var time = 0;
var tar_id = e.target.id;
var colors;
if(tar_id == 'line1' ) { colors = 'red'; }
else if(tar_id == 'line2' ) { time = 1000; colors = 'blue'; }
else if(tar_id == 'line3' ) { time = 2000; colors = 'green'; }
setTimeout(function(){
tarea.selectionStart = startPosition;
tarea.selectionEnd = endposition;
startPosition = endposition+1;
$('body').addClass(colors);
}, time);
});
});
#container {
float: left;
}
button {
width: 50px;height: 30px;
}
.red ::selection {
color: red;
background: yellow;
}
.blue ::selection {
color: blue;
background: red;
}
.green ::selection {
color: green;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<div id="container">
<button class="lines" id="line1">line 1</button>
<br>
<button class="lines" id="line2">line 2</button>
<br>
<button class="lines" id="line3">line 3</button>
</div>
<textarea id="str" rows="6"></textarea>

Categories