const addToCartButtons = document.getElementsByClassName('add-to-cart');
const addToCartButtonsArray = Array.from(addToCartButtons);
const increment = document.createElement('img');
increment.setAttribute('src', '/assets/images/icon-increment-quantity.svg');
increment.style.zIndex = '0';
increment.style.width = '15px';
increment.style.marginBottom = '0.5px';
increment.style.marginRight = '6px';
increment.style.border = 'none';
increment.style.cursor = 'pointer';
const decrement = document.createElement('img');
decrement.setAttribute('src', '/assets/images/icon-decrement-quantity.svg');
decrement.style.zIndex = '1';
decrement.style.width = '15px';
decrement.style.marginBottom = '0.5px';
decrement.style.marginLeft = '6px';
decrement.style.border = 'none';
decrement.style.cursor = 'pointer';
const quantity = document.createElement('span');
quantity.textContent = 0;
const addToCartButtonOnHover = document.createElement('div'); // new element when hovering
addToCartButtonOnHover.classList.add('add-to-cart-on-hover');
addToCartButtonsArray.forEach((button, index) => {
button.addEventListener('mouseover', (e) => {
const element = e.target.parentElement;
element.replaceChild(addToCartButtonOnHover, element.children[0]); // replaces old add-to-cart button with the hover one
addToCartButtonOnHover.append(decrement, quantity, increment);
let count = 0;
increment.onclick = function() {
count += 1;
quantity.textContent = count;
}
// adding and deducting products
decrement.onclick = function() {
count -= 1;
if (count < 0) {
count = 0;
}
quantity.textContent = count;
}
});
addToCartButtonOnHover.addEventListener('mouseleave', (e) => {
const element = e.target.parentElement;
element.replaceChild(addToCartButtonsArray[index], element.children[0]); // returns the old add-to-cart button
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Red Hat Text';
}
body {
display: flex;
height: 100vh;
justify-content: space-evenly;
}
.products {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: center;
}
.product {
flex-direction: column;
align-items: center;
width: 30%;
height: 43vh;
margin-left: 0;
margin-bottom: 5%;
margin: 50px;
}
.add-to-cart {
border: 1px solid hsl(14, 65%, 9%);
border-radius: 20px;
margin-left: 16%;
text-align: center;
width: 10vw;
height: 5vh;
line-height: 4.5vh;
background-color: white;
}
.add-to-cart-on-hover {
border: 1px solid hsl(14, 65%, 9%);
border-radius: 20px;
text-align: center;
margin-left: 16%;
display: flex;
justify-content: space-between;
align-items: center;
width: 10vw;
height: 5vh;
background-color: orange;
}
<div class="products">
<div class="product">
<div class="add-to-cart">Add to cart</div>
</div>
<div class="product">
<div class="add-to-cart">Add to cart</div>
</div>
</div>
Is it possible to somehow use an iterated element as a new child (the first argument) in the replaceChild() function? My code currently works as intended only on the first button because in the second event listener it's accessed like 'array[0]'. What I want is that the second button acts same as the first, but if I put something like 'array[1]' then the second button works but the first one disappears. I tried looping through the addToCartButtonsArray inside the event listener but it doesn't work. I want both buttons to work the same way.
forEach
has the index
as the second parameter of the callback, so you can define it and use it. Example:
let array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
array.forEach((item, index) => {
console.log(`${index}: ${item}`);
});
So you will have nothing else to do than specify your function as
addToCartButtonsArray.forEach((button, index) => {
//your code here
});
and then use [index]
instead of [0]
const addToCartButtons = document.getElementsByClassName('add-to-cart');
const addToCartButtonsArray = Array.from(addToCartButtons);
const increment = document.createElement('img');
increment.setAttribute('src', '/assets/images/icon-increment-quantity.svg');
increment.style.zIndex = '0';
increment.style.width = '15px';
increment.style.marginBottom = '0.5px';
increment.style.marginRight = '6px';
increment.style.border = 'none';
increment.style.cursor = 'pointer';
const decrement = document.createElement('img');
decrement.setAttribute('src', '/assets/images/icon-decrement-quantity.svg');
decrement.style.zIndex = '1';
decrement.style.width = '15px';
decrement.style.marginBottom = '0.5px';
decrement.style.marginLeft = '6px';
decrement.style.border = 'none';
decrement.style.cursor = 'pointer';
const quantity = document.createElement('span');
quantity.textContent = 0;
addToCartButtonsArray.forEach((button, index) => {
const addToCartButtonOnHover = document.createElement('div'); // new element when hovering
addToCartButtonOnHover.classList.add('add-to-cart-on-hover');
button.addEventListener('mouseover', (e) => {
const element = e.target.parentElement;
element.replaceChild(addToCartButtonOnHover, element.children[0]); // replaces old add-to-cart button with the hover one
addToCartButtonOnHover.append(decrement, quantity, increment);
let count = 0;
increment.onclick = function() {
count += 1;
quantity.textContent = count;
}
// adding and deducting products
decrement.onclick = function() {
count -= 1;
if (count < 0) {
count = 0;
}
quantity.textContent = count;
}
});
addToCartButtonOnHover.addEventListener('mouseleave', (e) => {
const element = e.target.parentElement;
element.replaceChild(addToCartButtonsArray[index], element.children[0]); // returns the old add-to-cart button
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Red Hat Text';
}
body {
display: flex;
height: 100vh;
justify-content: space-evenly;
}
.products {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: center;
}
.product {
flex-direction: column;
align-items: center;
width: 30%;
height: 43vh;
margin-left: 0;
margin-bottom: 5%;
margin: 50px;
}
.add-to-cart {
border: 1px solid hsl(14, 65%, 9%);
border-radius: 20px;
margin-left: 16%;
text-align: center;
width: 10vw;
height: 5vh;
line-height: 4.5vh;
background-color: white;
}
.add-to-cart-on-hover {
border: 1px solid hsl(14, 65%, 9%);
border-radius: 20px;
text-align: center;
margin-left: 16%;
display: flex;
justify-content: space-between;
align-items: center;
width: 10vw;
height: 5vh;
background-color: orange;
}
<div class="products">
<div class="product">
<div class="add-to-cart">Add to cart</div>
</div>
<div class="product">
<div class="add-to-cart">Add to cart</div>
</div>
</div>