Changing button class with javascript is not working - javascript

I have three button. Each of them change backgroud of banner section. I want to set active class on them when clicked. I was trying to take array of buttons and iterate through them but something is not working. Could you tell me what am I doing wrong?
Here is the code:
const banner = document.getElementById('carousel');
const btns = banner.getElementsByClassName('button');
for (const i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
const current = document.getElementsByClassName('active');
current[0].className = current[0].className.replace('active', '');
this.className += 'active';
})
};
.carousel {
top: 50%;
position: absolute;
}
.carousel .button {
height: 10px;
width: 10px;
border: 2px solid black;
margin: 10px;
border-radius: 9px;
position: relative;
cursor: pointer;
}
.carousel .button .active {
position: absolute;
margin-top: 3px;
margin-left: 3px;
height: 4px;
width: 4px;
border-radius: 5px;
background: #fea100;
}
<div class="carousel" id="carousel">
<div class="button" id="button1">
<div class="active"></div>
</div>
<div class="button" id="button2">
<div></div>
</div>
<div class="button" id="button3">
<div></div>
</div>
</div>

The keyword this is referring the clicked button. You should target the div inside this. You can use remove() and add() to remove/add class to the elements:
Try the following way:
let banner = document.getElementById('carousel');
let btns = banner.getElementsByClassName('button');
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
let current = document.getElementsByClassName('active');
current[0].className = current[0].classList.remove('active');
this.querySelector('div').classList.add('active');
})
}
.carousel {
top: 50%;
position: absolute;
}
.carousel .button {
height: 10px;
width: 10px;
border: 2px solid black;
margin: 10px;
border-radius: 9px;
position: relative;
cursor: pointer;
}
.carousel .button .active {
position: absolute;
margin-top: 3px;
margin-left: 3px;
height: 4px;
width: 4px;
border-radius: 5px;
background: #fea100;
}
<div class="carousel" id="carousel">
<div class="button" id="button1">
<div class="active"></div>
</div>
<div class="button" id="button2">
<div></div>
</div>
<div class="button" id="button3">
<div></div>
</div>
</div>
You can also use querySelectorAll() and forEach() like the following way:
let btns = document.querySelectorAll('.button');
let divs = document.querySelectorAll('.button > div');
btns.forEach(function(btn){
btn.addEventListener('click', function() {
document.querySelector('.active').classList.remove('active');
this.firstElementChild.classList.add('active');
});
})
.carousel {
top: 50%;
position: absolute;
}
.carousel .button {
height: 10px;
width: 10px;
border: 2px solid black;
margin: 10px;
border-radius: 9px;
position: relative;
cursor: pointer;
}
.carousel .button .active {
position: absolute;
margin-top: 3px;
margin-left: 3px;
height: 4px;
width: 4px;
border-radius: 5px;
background: #fea100;
}
<div class="carousel" id="carousel">
<div class="button" id="button1">
<div class="active"></div>
</div>
<div class="button" id="button2">
<div></div>
</div>
<div class="button" id="button3">
<div></div>
</div>
</div>

Related

How to get access and change style of an element with JavaScript?

I am coding a survey. If a button is clicked the color of the clicked button is changing. I want to provide the possibility to the user to deselect a button if he for example clicked or selected respectively the wrong button. Therefore, I changed the class of the selected button to have a exclusive access only to the selected button to set the style-attributes to default when deselect the button. I tried different ways but none of them worked. Where is my failure? My code is below.
window.onload = function() {
const option = document.getElementsByClassName("button");
const forward = document.getElementById("forward");
Array.from(option).forEach(function(option) {
option.addEventListener("click", () => {
option.style.backgroundColor = "rgb(77, 55, 120)";
option.style.opacity = "0.65";
option.style.color = "white";
//Changong buttons backgroundcolor to purple
let keySelector = option.querySelector(".key-selector");
keySelector.style.color = "white";
//determine the key-selector and turn the color into white
forward.style.color = "white";
forward.style.backgroundColor = "rgb(77, 55, 120)";
forward.style.transition = "1s ease";
//changing the color of the continue-button to purple when at least one element is selected
option.className = "selected-button";
console.log(option.className);
//replace class name of selected-element to provide the possibility to have access to the selected element in order to deselect if required
});
});
const selectedButton = document.getElementsByClassName("selected-button");
Array.from(selectedButton).forEach(function(selectedButton) {
selectedButton.addEventListener("click", () => {
//if selected element is clicked again turn the style-settings to default
keySelector.style.color = "rgb(51, 51, 51)";
keySelector.style.opacity = "0.6";
selectedButton.style.backgroundColor = "rgb(226, 226, 226)";
selectedButton.style.color = "black";
selectedButton.style.opacity = "1";
//return the colors when a button is deselected
selectedButton.className = "button";
console.log(option.className);
//turn the class name to default to have provide the possibility to select the element again
});
});
};
body {
font-family: 'Noto Sans Avestan', sans-serif;
}
.navbar {
display: flex;
list-style: none;
background-color: rgb(77, 55, 120);
margin: 0;
position: fixed;
width: 100%;
gap: 4rem;
height: 50px;
text-align: center;
line-height: 45px;
left: 0;
top: 0;
}
.nav-text {
text-decoration: none;
color: white;
width: auto;
cursor: pointer;
font-size: 18px;
padding-bottom: 5px;
}
.instruction {
padding-top: 8rem;
left: 10%;
padding-bottom: 0px;
width: auto;
max-width: 730px;
font-size: 20px;
position: absolute;
}
.options {
height: auto;
max-height: 313px;
max-width: 750px;
width: auto;
padding-top: 15rem;
padding-bottom: 60px;
display: flex;
flex-direction: column;
gap: 15px;
position: sticky;
left: 8rem;
}
.button,
.selected-button {
background-color: rgb(226, 226, 226);
height: 418.75%;
width: auto;
padding: 21px 25px 22px 25px;
box-sizing: border-box;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
cursor: pointer;
font-size: 18px;
line-height: 16.8px;
display: block;
position: relative;
top: 0px;
bottom: 0px;
right: 0px;
left: 0px;
}
.text {
margin-left: 4rem;
}
.button:hover {
background-color: rgb(194, 194, 194);
opacity: 0.8;
}
#backward:hover,
#forward:hover {
background-color: rgb(77, 55, 120);
color: white;
}
.key-selector {
position: absolute;
top: 50%;
margin-top: -12px;
font-size: 16px;
line-height: 1.5em;
text-align: center;
width: 30px;
display: block;
opacity: 0.6;
border: 1px solid;
border-radius: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
height: 25px;
color: rgb(51, 51, 51);
}
.button:hover .key-selector {
color: black;
}
.button-bar {
position: fixed;
bottom: 0;
width: 100%;
display: flex;
margin: 0;
left: 0;
}
.nav-inner {
cursor: pointer;
width: 50%;
text-align: center;
line-height: 83px;
}
#backward {
background-color: rgb(101, 93, 93);
color: white;
}
#forward {
background-color: rgb(191, 191, 191);
}
<div id="work-container">
<ul class="navbar">
<li class="section"><a class="nav-text" href="client.html">A</a></li>
<li class="section"><a class="nav-text" href="case.html" style=" border-bottom: 1px solid;">B</a></li>
</ul>
<div class="instruction">
<h3>Please choose an answer. You can choose more than one answers.</h3>
</div>
<div class="options">
<div class="option">
<div class="button">
<div class="key-selector">
<span>A</span>
</div>
<div class="text">1</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>B</span>
</div>
<div class="text">2</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>C</span>
</div>
<div class="text">3</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>D</span>
</div>
<div class="text">4</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>E</span>
</div>
<div class="text">5</div>
</div>
</div>
</div>
<div class="button-bar">
<div class="nav-inner" id="backward">
< Back</div>
<div class="nav-inner" id="forward"> Continue ></div>
</div>
</div>
</div>
You're only looping over selectedButtons when the page first loads. Since there are no elements with the class at that time, nothing gets the second event listener.
Instead of two different event listeners, use a single event listener that tests the class of the element.
if (option.classList.contains("selected-button")) {
// do something
} else {
// do somthing else
}
It's also generally better to use the classList methods than assigning to className, so you don't remove other, unrelated classes. This would allow you to add/remove the selected-button class without removing button, so you don't need to assign the same style to both classes in CSS.
window.onload = function() {
const option = document.getElementsByClassName("button");
const forward = document.getElementById("forward");
Array.from(option).forEach(function(option) {
option.addEventListener("click", () => {
let keySelector = option.querySelector(".key-selector");
if (option.classList.contains("selected-button")) {
let selectedButton = option;
//if selected element is clicked again turn the style-settings to default
keySelector.style.color = "rgb(51, 51, 51)";
keySelector.style.opacity = "0.6";
selectedButton.style.backgroundColor = "rgb(226, 226, 226)";
selectedButton.style.color = "black";
selectedButton.style.opacity = "1";
//return the colors when a button is deselected
selectedButton.classList.remove("selected-button");
console.log(option.className);
//turn the class name to default to have provide the possibility to select the element again
} else {
option.style.backgroundColor = "rgb(77, 55, 120)";
option.style.opacity = "0.65";
option.style.color = "white";
//Changong buttons backgroundcolor to purple
keySelector.style.color = "white";
//determine the key-selector and turn the color into white
forward.style.color = "white";
forward.style.backgroundColor = "rgb(77, 55, 120)";
forward.style.transition = "1s ease";
//changing the color of the continue-button to purple when at least one element is selected
option.classList.add("selected-button");
console.log(option.className);
//replace class name of selected-element to provide the possibility to have access to the selected element in order to deselect if required
}
});
});
};
body {
font-family: 'Noto Sans Avestan', sans-serif;
}
.navbar {
display: flex;
list-style: none;
background-color: rgb(77, 55, 120);
margin: 0;
position: fixed;
width: 100%;
gap: 4rem;
height: 50px;
text-align: center;
line-height: 45px;
left: 0;
top: 0;
}
.nav-text {
text-decoration: none;
color: white;
width: auto;
cursor: pointer;
font-size: 18px;
padding-bottom: 5px;
}
.instruction {
padding-top: 8rem;
left: 10%;
padding-bottom: 0px;
width: auto;
max-width: 730px;
font-size: 20px;
position: absolute;
}
.options {
height: auto;
max-height: 313px;
max-width: 750px;
width: auto;
padding-top: 15rem;
padding-bottom: 60px;
display: flex;
flex-direction: column;
gap: 15px;
position: sticky;
left: 8rem;
}
.button {
background-color: rgb(226, 226, 226);
height: 418.75%;
width: auto;
padding: 21px 25px 22px 25px;
box-sizing: border-box;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
cursor: pointer;
font-size: 18px;
line-height: 16.8px;
display: block;
position: relative;
top: 0px;
bottom: 0px;
right: 0px;
left: 0px;
}
.text {
margin-left: 4rem;
}
.button:hover {
background-color: rgb(194, 194, 194);
opacity: 0.8;
}
#backward:hover,
#forward:hover {
background-color: rgb(77, 55, 120);
color: white;
}
.key-selector {
position: absolute;
top: 50%;
margin-top: -12px;
font-size: 16px;
line-height: 1.5em;
text-align: center;
width: 30px;
display: block;
opacity: 0.6;
border: 1px solid;
border-radius: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
height: 25px;
color: rgb(51, 51, 51);
}
.button:hover .key-selector {
color: black;
}
.button-bar {
position: fixed;
bottom: 0;
width: 100%;
display: flex;
margin: 0;
left: 0;
}
.nav-inner {
cursor: pointer;
width: 50%;
text-align: center;
line-height: 83px;
}
#backward {
background-color: rgb(101, 93, 93);
color: white;
}
#forward {
background-color: rgb(191, 191, 191);
}
<div id="work-container">
<ul class="navbar">
<li class="section"><a class="nav-text" href="client.html">A</a></li>
<li class="section"><a class="nav-text" href="case.html" style=" border-bottom: 1px solid;">B</a></li>
</ul>
<div class="instruction">
<h3>Please choose an answer. You can choose more than one answers.</h3>
</div>
<div class="options">
<div class="option">
<div class="button">
<div class="key-selector">
<span>A</span>
</div>
<div class="text">1</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>B</span>
</div>
<div class="text">2</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>C</span>
</div>
<div class="text">3</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>D</span>
</div>
<div class="text">4</div>
</div>
</div>
<div class="option">
<div class="button">
<div class="key-selector">
<span>E</span>
</div>
<div class="text">5</div>
</div>
</div>
</div>
<div class="button-bar">
<div class="nav-inner" id="backward">
< Back</div>
<div class="nav-inner" id="forward"> Continue ></div>
</div>
</div>
</div>
Let me tell you the mistakes in your code.
Array.from(option).forEach(function (option) {
is a very wrong way to add event listeners. Use event delegation.
option.className = "selected-button";
is a wrong way to add class. Use classlist.add()/classlist.remove().
const selectedButton = document.getElementsByClassName("selected-button");
You are adding a query of selected-button at the time of window load. You will not get any element in this case, because classname will be added if button is selected, and will not be present at the time of load. Event delegation will save you again.
element.style.backgroundColor = "purple"
This again is a piece of text from another world. Create a CSS class, .active and add/remove the CSS class.
You literally need 0 javascript for this part. CSS has the :focus and :disabled pseudoclasses, and HTML has the "disabled" attribute and automatically sets the focused element for CSS (:focus is the selected button/input):
button {
color: black;
background: aqua;
border: none;
border-radius: 5px;
padding: 4px 5px;
transition-duration: 0.2s;
}
button:disabled {
background: silver;
color: gray;
}
button:focus {
background: #aaf;
outline: 2px solid aqua;
}
<button disabled>Disabled</button>
<button>Back</button>
<button>Next</butotn>
There's also the HTML form element, which can have required fields of different types:
<form>
<input type="number" placeholder="Number"><br>
<input type="password" placeholder="Password"><br>
<input type="text" placeholder="Required text" required><br>
<input type="date"><br>
<input type="submit" value="Send"><br>
</form>

How to add javascript onclick event listener to container div?

Add onclick event listener to container div.
I tried the following, and as you can see, the event does not seem to be registered. How can I add the listener to this div?
The div id I want is "engineersContainer."
document.getElementById("engineersContainer").addEventListener("click", function(e) {
console.log("It was clicked");
alert("It was clicked");
});
.barContainer {
margin: 2px;
border: 2px solid black;
border-radius: 20px;
width: 200px;
//width:-moz-fit-content;
//width: fit-content;
padding: 5px;
overflow: hidden;
position: relative;
background: #34e8eb;
z-index: -1;
}
.containerHeader:before {
content:"";
background: skyblue;
position: absolute;
inset: 0;
z-index: -1;
height:45px
}
<div id="engineersContainer" class="barContainer">
<div id="engineerList" class="containerHeader" style="font-size:1.5em; text-align:center">Current Engineer </div>
<div> Engineer's Name</div>
<div id="clickText" style="padding-bottom: 10px; font-size:0.75em; text-align:center "> (Click to See All Permits) </div>
</div>
Remove the -1 z-index, otherwise it will be under the rest of the page
Add the event listener in the page load event
See second example for a workaround
window.addEventListener("load", function() {
document.getElementById("engineersContainer")
.addEventListener("click", function(e) {
console.log("It was clicked");
});
});
.barContainer {
margin: 2px;
border: 2px solid black;
border-radius: 20px;
width: 200px;
//width:-moz-fit-content;
//width: fit-content;
padding: 5px;
overflow: hidden;
position: relative;
background: #34e8eb;
/* z-index: -1 */
}
.containerHeader:before {
content: "";
background: skyblue;
position: absolute;
inset: 0;
z-index: -1;
height: 45px
}
.containerHeader {
font-size: 1.5em;
text-align: center
}
#clickText {
padding-bottom: 10px;
font-size: 0.75em;
text-align: center
}
<div id="engineersContainer" class="barContainer">
<div id="engineerList" class="containerHeader">Current Engineer </div>
<div> Engineer's Name</div>
<div id="clickText"> (Click to See All Permits) </div>
</div>
Otherwise add another div on top of it
window.addEventListener("load", function() {
document.getElementById("engineersContainerClick").addEventListener("click", function(e) {
console.log("It was clicked");
});
});
.barContainer {
margin: 2px;
border: 2px solid black;
border-radius: 20px;
width: 200px;
//width:-moz-fit-content;
//width: fit-content;
padding: 5px;
overflow: hidden;
position: relative;
background: #34e8eb;
z-index: -1
}
#engineersContainerClick {
margin: 2px;
border-radius: 20px;
width: 200px;
height:70px;
padding: 5px;
border:none;
overflow: hidden;
position: absolute;top:0;
background-color: transparent;
z-index:999;
}
.containerHeader:before {
content: "";
background: skyblue;
position: absolute;
inset: 0;
z-index: -1;
height: 45px
}
.containerHeader {
font-size: 1.5em;
text-align: center
}
#clickText {
padding-bottom: 10px;
font-size: 0.75em;
text-align: center
}
<div id="engineersContainer" class="barContainer">
<div id="engineerList" class="containerHeader">Current Engineer </div>
<div> Engineer's Name</div>
<div id="clickText"> (Click to See All Permits) </div>
</div>
<div id="engineersContainerClick" class="barContainer">
You need to remove the z-index: -1 in your CSS.
Any user clicks are not making contact with the element, but with the document above the element.
Working Example:
document.getElementById("engineersContainer").addEventListener("click", function(e) {
console.log("It was clicked");
alert("It was clicked");
});
.barContainer {
margin: 2px;
border: 2px solid black;
border-radius: 20px;
width: 200px;
/* width:-moz-fit-content; */
/* width: fit-content; */
padding: 5px;
overflow: hidden;
position: relative;
background: #34e8eb;
}
.containerHeader:before {
content:"";
background: skyblue;
position: absolute;
inset: 0;
z-index: -1;
height:45px
}
<div id="engineersContainer" class="barContainer">
<div id="engineerList" class="containerHeader" style="font-size:1.5em; text-align:center">Current Engineer </div>
<div> Engineer's Name</div>
<div id="clickText" style="padding-bottom: 10px; font-size:0.75em; text-align:center "> (Click to See All Permits) </div>
</div>
document.getElementById("engineersContainer").onclick=function(){
console.log("your event");
}
.barContainer {
margin: 2px;
border: 2px solid black;
border-radius: 20px;
width: 200px;
//width:-moz-fit-content;
//width: fit-content;
padding: 5px;
overflow: hidden;
position: relative;
background: #34e8eb;
}
.containerHeader:before {
content:"";
background: skyblue;
position: absolute;
inset: 0;
z-index: -1;
height:45px
}
<body>
<div id="engineersContainer" class="barContainer">
<div id="engineerList" class="containerHeader" style="font-size:1.5em; text-align:center">Current Engineer </div>
<div> Engineer's Name</div>
<div id="clickText" style="padding-bottom: 10px; font-size:0.75em; text-align:center "> (Click to See All Permits) </div>
</div>
</body>
ng-js -->
document.getElementById("engineersContainer").onclick=function(){
console.log("your event");
}
<div id="engineersContainer"> Here is the Engineers Container
</div>
I would use an anonymous function for this. You must call the script after your div has been created, as Javascript is read top to bottom and will not have a reference if it is run before the div has been placed.
Beware that if you have a listener on the container div, it will impact your ability to introduce any clickable options within the divs child elements such as buttons later on. Could this cause you problems in the future? If so rethink the design possibly to save you some trouble later. Also, the negative Z index needs to be removed as it is being drawn beneath the layer that Javascript detects the clicks. Sorry for the edits I'm new to StackO.

How can I make this calendar close correctly?

I got this code off of codepen and I am trying to edit it. I am trying to make it so that when you actually click the X in the corner of the popup, the box actually closes, and that after hitting the add button after putting in text, the box closes. Can anyone help me accomplish this? I am having trouble getting it to work. Any help is appreciated. Thanks!
https://codepen.io/pokyparachute66/pen/QzXYjL
var date = document.getElementsByClassName("day");
for(i = 0; i < 50; i++){
var event = document.createElement("div");
event.id = "add";
event.innerHTML = "<p>Add Phone Number</p><input type='text'> <span
class='close'><i class='fa fa-times' aria-hidden='true'></i></span>";
date[i].appendChild(event);
var btn = document.createElement("button");
btn.innerHTML = "<i class='fa fa-plus' aria-hidden='true'></i>";
event.appendChild(btn);
btn.addEventListener("click", createEvent);
date[i].addEventListener("click", clickEvent);
event.getElementsByClassName("close")[0].addEventListener("click",
closeEvent);
}
function createEvent(){
var parent = this.parentElement;
var parentDay = parent.parentElement;
if(parent.getElementsByTagName("input")[0].value === "" ){
alert("type something");
}
else{
var createDiv = document.createElement("div");
createDiv.id = "eventDiv";
parent.appendChild(createDiv);
parentDay.classList.add("active");
var txt = parent.getElementsByTagName("input")[0].value;
createDiv.innerHTML = txt;
parent.getElementsByTagName("input")[0].value = "";
//parent.style.visibility = "visible";
}
}
function clickEvent(){
var a = this.getElementsByTagName("div")[0];
a.classList.toggle("active");
}
function closeEvent(){
document.getElementById("add").classList.remove("active");
}
button:focus, input:focus{outline: none;}
.calendar{
margin: calc(50vh - 100px) auto 0 auto;
width: 260px;
height: 200px;
text-align: center;
transform: scale(2.5);
}
.day{
position: relative;
margin: 2px;
width: 33px;
height: 33px;
font-size: 12px;
line-height: 30px;
border-radius: 100%;
float: left;
cursor: pointer;
transition: all .4s ease 0s;
}
.day:hover{
color: #fff;
background: #3f64fd;
}
.day-week{
margin: 0px;
width: 37px;
height: 20px;
color: #515067;
font-size: 9px;
line-height: 20px;
text-transform: uppercase;
float: left;
}
.blank{
margin: 0px ;
width: 37px;
height: 37px;
float: left;
}
#add{
padding: 15px;
position: absolute;
left: -90px;
bottom: 50px;
width: 200px;
min-height: 50px;
background: linear-gradient(to top left, #3f64fd, #14c0ff);
transition: all .2s ease 0s;
visibility: hidden;
opacity: 0;
box-shadow: 0 0 25px rgba(0,0,0,.6);
}
#add.active,
#add:hover{
bottom: 30px;
visibility: visible;
opacity: 1;
transition: all .4s ease 0s;
z-index: 999;
}
#add .close{
position: absolute;
top: 0px;
right: 5px;
color: white;
}
#add input[type="text"]{
width: 140px;
padding: 3px 5px;
color: #fff;
background: none;
border: none;
border-bottom: 1px solid white;
}
#add button{
height: 50px;
width: 50px;
color: #fff;
line-height: 23px;
text-align: center;
background: #3f64fd;
border: none;
left: 70%;
top:53%;
position: absolute;
border-radius: 100%;
cursor: pointer;
}
#eventDiv{
padding: 5px;
line-height: 12px;
text-align: left;
}
.day.active{
color: black;
border: 2px solid #3f64fd;
}
<div class="calendar">
<div class="day-week">s</div>
<div class="day-week">m</div>
<div class="day-week">t</div>
<div class="day-week">w</div>
<div class="day-week">t</div>
<div class="day-week">f</div>
<div class="day-week">s</div>
<div class="blank"></div>
<div class="blank"></div>
<div class="day">1</div>
<div class="day">2</div>
<div class="day">3</div>
<div class="day">4</div>
<div class="day">5</div>
<div class="day">6</div>
<div class="day">7</div>
<div class="day">8</div>
<div class="day">9</div>
<div class="day">10</div>
<div class="day">11</div>
<div class="day">12</div>
<div class="day">13</div>
<div class="day">14</div>
<div class="day">15</div>
<div class="day">16</div>
<div class="day">17</div>
<div class="day">18</div>
<div class="day">19</div>
<div class="day">20</div>
<div class="day">21</div>
<div class="day">22</div>
<div class="day">23</div>
<div class="day">24</div>
<div class="day">25</div>
<div class="day">26</div>
<div class="day">27</div>
<div class="day">28</div>
<div class="day">29</div>
<div class="day">30</div>
<div class="day">31</div>
</div>
Instead of doing that really complicated thing why you should do something like:
<input type="date">
I don't understand what are you trying to accomplish!
It's closing when you hit X or + BUT the code is really confusing...
It's creating a div element with id="add" around 50 times?!
for(i = 0; i < 50; i++){
var event = document.createElement("div");
event.id = "add"; // should make this event.className = 'add';
event.innerHTML = "<p>Add Phone Number</p><input type='text'> <span class='close'><i class='fa fa-times' aria-hidden='true'></i></span>";
date[i].appendChild(event);
DO NOT FORGET to change CSS (#add -> .add) and closing event (getElementById -> getElementsByClassName)
During the closeEvent function, you're removing the 'active' class, but the element doesn't have that class. So it's not closing the popup until you've moused away from the box itself.
I would remove the closeEvent function and the reference to it on line 18 of your JS, and would change the clickEvent() function to something like this:
function clickEvent(){
var a = this.getElementsByTagName("div")[0];
a.classList.toggle("active");
if (!a.classList.contains('active')) {
var parentOfA = a.parentNode;
parentOfA.removeChild(a);
}
}
That way you're removing the element from the document entirely, rather than just changing the class on it.

JS - Click event not working as it should

Maybe some of you can help me solve this problem.
I have this code and I made like an extension for the product that will show product description when click on product. But the on click function isn't working (can't close description).
Thanks!
$('.product').on('click', function(){
$('.product .productExtension').css("display","none");
$(this).children(".productExtension").css("display","block");
});
function close(){
$('.productExtension').css("display","none");
}
.product{
position: relative;
width: 80px; height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center; font-family: Arial;
}
.product > .productExtension{
position: fixed;
top: 50%; left: 50%; transform: translate(-50%,-50%);
width: 300px; height: 200px;
padding: 20px;
background: red;
text-align: left;
display: none;
}
.product > .productExtension > .closeProductExtension{
position: absolute;
top: -40px; left: 0;
width: 20px; height: 20px;
margin: 10px;
border: none;
background: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
<div class="closeProductExtension" onclick="close()">Close</div>
</div>
</div>
Now I know it wasn't fully part of the question, and I took a bit of liberty with the styling, but there is absolutely no need to hide all different productExtension classes upon each close. It would be far lighter to read the properties detailed inside your product div, and render them to a modal.
It does have an overly complex way of closing the modal ( just some liberties at work there, I am sorry for that one :) )
The answer that is currently accepted both details the reason why you cannot use close (could be window.close), I just thought the offer a different perspective when you have more than one product how to transfer the data between a modal and your DOM as you describe it now. I think it has its advantages
window.addEventListener( 'load', function() {
document.querySelectorAll('.product').forEach( product => {
product.addEventListener('click', handleProductClicked, false );
} );
document.querySelectorAll('[data-action]').forEach( action => {
action.addEventListener('click', handleAction );
} );
function handleAction( e ) {
const owner = e.currentTarget;
const action = owner.getAttribute('data-action');
const selector = owner.getAttribute('data-target');
const target = document.querySelector( selector );
if (action === 'hide') {
if ( !target.classList.contains('hidden') ) {
target.classList.add('hidden');
}
}
}
function showModal( title, content, owner ) {
const modal = document.querySelector('#modal');
if ( modal.classList.contains('hidden') ) {
modal.classList.remove( 'hidden' );
}
modal.querySelector('[data-for=title]').innerText = title;
modal.querySelector('[data-for=content]').innerHTML = content;
}
function handleProductClicked( e ) {
const productContainer = e.currentTarget;
const name = productContainer.querySelector('.productName').innerText;
const description = productContainer.querySelector('.productExtension').innerHTML;
showModal( name, description, productContainer );
}
} );
.hidden {
display: none;
visibility: hidden;
}
.productExtension {
display: none;
visibility: hidden;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 200px;
border: solid #a0a0a0 1px;
box-shadow: 5px 3px 5px #777;
background-color: #cfcfcf;
}
.modal > .title {
position: absolute;
left: 0px;
top: 0px;
right: 0px;
height: 20px;
font-size: 0.9em;
background-color: blue;
border-bottom: solid #fff 1px;
}
.modal > .title > .controls {
position: absolute;
right: 0px;
top: 0px;
width: 20px;
height: 18px;
background-color: #efefef;
border: solid #a0a0a0 1px;
text-align: center;
text-transform: small-caps;
}
.controls:hover {
font-weight: bold;
cursor: pointer;
}
.modal > .title > [data-for] {
padding: 3px;
color: #fff;
font-weight: 800;
}
.modal > .content {
position: absolute;
left: 0px;
right: 0px;
top: 21px;
bottom: 0px;
padding: 5px;
border: inset #666 1px;
}
.product {
position: relative;
width: 80px;
height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center;
font-family: Arial;
}
<div class="modal hidden" id="modal">
<div class="title">
<span data-for="title"></span>
<div class="controls">
<span data-action="hide" data-target="#modal">X</span>
</div>
</div>
<div class="content" data-for="content">
</div>
</div>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
</div>
</div>
<div class="product">
<div class="productName">Blue Hoodie</div>
<div class="productPrice">14.75$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in blue color</div>
</div>
</div>
This is happening because both functions trigger. The first trigger because you are clicking on an item that is inside the DIV “product” and the second because you’ve passed the function to the onClick. You should take out the “productExtension” div from “product” to make it works.
As mentioned in other comments, you have two click handler in the parent and child. The parent div is intercepting all click events. Try this for your requirement.
$(".product").on("click", function(e) {
$(".product .productExtension").css("display", "none");
$(this)
.children(".productExtension")
.css("display", "block");
if (e.target.classList.contains('closeProductExtension')) {
$(".productExtension").css("display", "none");
}
});
You have several problems. The first is that you trigger the open event as well. To solve this you can use stop propagation. The second is that you are using the method name "close" which is already used in JS.
$('.product').on('click', function() {
$('.product .productExtension').css("display", "none");
$(this).children(".productExtension").css("display", "block");
});
function closeE(event) {
event.stopPropagation();
$('.productExtension').css("display", "none");
}
.product {
position: relative;
width: 80px;
height: 160px;
padding: 20px;
border: solid 1px grey;
text-align: center;
font-family: Arial;
}
.product>.productExtension {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height: 200px;
padding: 20px;
background: red;
text-align: left;
display: none;
}
.product>.productExtension>.closeProductExtension {
position: absolute;
top: -40px;
left: 0;
width: 20px;
height: 20px;
margin: 10px;
border: 1px solid black;
background: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="product">
<div class="productName">Red Hoodie</div>
<div class="productPrice">14.72$</div>
<div class="productExtension">
<div class="productDescription">This hoodie is in red color</div>
<div class="closeProductExtension" onclick="closeE(event)">Close</div>
</div>
</div>

Two divs to simultaneously animate

I am attempting to create a simple slide show type feature on a web page. I have created the slide show, but run into issues smoothly transitioning the next slide into frame when the user presses the 'next slide' button. Here is my code
var $slideshow = $('#slideshow');
var sswidth = $slideshow.width();
var ssheight = $slideshow.height();
var currentslide = 0;
$('.slide').eq(currentslide).addClass('show');
$('.btnslideshow.right').click(function(){
var left = $('.slide.show').offset().left;
$('.slide.show').animate({'left': '+=' + sswidth + 'px'}, 'slow', function(){
$('.slide').eq(currentslide).removeClass('show');
$('.slide').eq(currentslide).css({left: '0px'});
currentslide+=1;
if (currentslide > $('.slide').length-1) currentslide = 0;
$('.slide').eq(currentslide).addClass('show', 'slow');
});
});
.background {
background-color: lightgray;
border-color: gray;
border-style: solid;
border-width: 1px 0 1px 0;
width: 100%;
}
.btnslideshow {
background: lightgray;
height: 25px;
position: relative;
top: 77.5px;
width: 25px;
box-sizing: border-box;
border-style:inset;
z-index: 1;
}
.btnslideshow:hover {
background: lightblue;
border-style:outset;
}
.btnslideshow.left {
float: left;
left: 7%;
transform: rotate(180deg);
}
.btnslideshow.right {
float:right;
right: 7%;
}
#nav {
height: 25px;
text-align: right;
}
.navHeader {
border: none;
background-color: transparent;
display: inline;
font-size: 13px;
font-variant: small-caps;
font-weight: 600;
padding-right: 20px;
}
.navHeader:nth-child(1) {
margin-right:10px;
}
.navHeader:hover {
font-size: 16px;
}
.show {
display:inline-block !important;
}
#slideshow {
background-color: white;
border: 1px solid black;
height:200px;
margin-left: 12.5%;
overflow:hidden;
width:75%;
}
.slide {
border:1px solid black;
display: none;
height:100%;
position:relative;
width:0px;
z-index: 0;
}
.slide.show {
width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav">
<div class="navone">
<button class="navHeader">
About
</button>
<button class="navHeader">
Contact
</button>
</div>
</div>
<div id="container">
<div class="background">
<img class="btnslideshow left" src="https://cdn3.iconfinder.com/data/icons/buttons/512/Icon_22-512.png">
<img class="btnslideshow right" src="https://cdn3.iconfinder.com/data/icons/buttons/512/Icon_22-512.png">
<div id="slideshow">
<div class="slide">
Test slide
</div>
<div class="slide">
Test slide 22222
</div>
</div>
</div>
</div>
As you can see, my slide show is essentially working, but the transition is pretty rough. What I am wanting is for the second slide to move into frame while the first slide is moving out, with no space in between them. I have tried animating the width on the second slide inside the callback function of the first animation, outside the first animation, and other things but I can't seem to get it.
I made quite a few changes in your code.
I made the #slideshow div position:relative and the slides position:abosulte. Then made some over all changes in the js structure, Introduced the queue:false in the animate function, etc.
var $slideshow = $('#slideshow');
var sswidth = $slideshow.width();
var ssheight = $slideshow.height();
var currentslide = 0;
var duration = 1000;
$('.slide').eq(currentslide).addClass('show');
$('.slide').not('.show').css('left', -(sswidth+3) + 'px');
$('.btnslideshow.right').click(function() {
var left = $('.slide.show').offset().left;
$('.slide.show').animate({
'left': sswidth + 'px'
}, {
duration: duration,
queue: false,
complete:function(){
$(this).delay(20).css('left', -(sswidth+3) + 'px').removeClass('show');
}
});
currentslide++;
if (currentslide > $('.slide').length - 1) currentslide = 0;
$('.slide').eq(currentslide).animate({
left: '0px'
}, {
duration: duration,
queue: false
}).delay(duration).addClass('show');
});
.background {
background-color: lightgray;
border-color: gray;
border-style: solid;
border-width: 1px 0 1px 0;
width: 100%;
}
.btnslideshow {
background: lightgray;
height: 25px;
position: relative;
top: 77.5px;
width: 25px;
box-sizing: border-box;
border-style: inset;
z-index: 1;
}
.btnslideshow:hover {
background: lightblue;
border-style: outset;
}
.btnslideshow.left {
float: left;
left: 7%;
transform: rotate(180deg);
}
.btnslideshow.right {
float: right;
right: 7%;
}
#nav {
height: 25px;
text-align: right;
}
.navHeader {
border: none;
background-color: transparent;
display: inline;
font-size: 13px;
font-variant: small-caps;
font-weight: 600;
padding-right: 20px;
}
.navHeader:nth-child(1) {
margin-right: 10px;
}
.navHeader:hover {
font-size: 16px;
}
.show {
display: inline-block !important;
}
#slideshow {
background-color: white;
border: 1px solid black;
height: 200px;
margin-left: 12.5%;
overflow: hidden;
width: 75%;
position:relative;
}
.slide {
border: 1px solid black;
height: 100%;
position: absolute;
width: 100%;
z-index: 0;
display:none;
}
.slide.show {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nav">
<div class="navone">
<button class="navHeader">
About
</button>
<button class="navHeader">
Contact
</button>
</div>
</div>
<div id="container">
<div class="background">
<img class="btnslideshow left" src="https://cdn3.iconfinder.com/data/icons/buttons/512/Icon_22-512.png">
<img class="btnslideshow right" src="https://cdn3.iconfinder.com/data/icons/buttons/512/Icon_22-512.png">
<div id="slideshow">
<div class="slide">Test slide</div>
<div class="slide">Test slide 22222</div>
</div>
</div>
</div>

Categories

Resources