'Hovering over all buttons in vanilla JS
I need the refresh_button to appear and disappear only on mouseover/mouseout on the avatar(image).
I've build this functionality and it works, however, it appears on image hover + on span hover too.
Could you please spot what's wrong?
When I use the same code on .avatar class it doesn't work, I think the .r reference is null in that case. I need to use vanilla JavaScript.
Thank you
document.querySelectorAll(".tree").forEach(img => {
img.onmouseover = function () {
let refresh_button = img.querySelector(".r");
refresh_button.style.opacity = 1;
};
img.onmouseout = function () {
let refresh_button = img.querySelector(".r");
refresh_button.style.opacity = 0;
};
});
#no1 {
display: flex;
justify-content: center;
width: 190px;
line-height: 16px;
margin: auto;
}
.container1 {
width: 580px;
font-family: verdana, arial, helvetica, sans-serif;
font-weight: bold;
font-size: 11px;
text-align: center;
margin: auto;
}
.namefunc {
display: flex;
justify-content: center;
gap: 10px;
}
.name {
background: #beebb3;
border-color: #606f46;
border-radius: 22px 0 22px 0;
padding: 2px;
padding-bottom: 5px;
border-style: solid;
margin-top: 5px;
box-shadow: 4px 4px 13px #222;
width: 145px;
color: green;
}
.name_input {
background: #beebb3;
border: none;
text-align: center;
margin-left: 5px;
margin: 4px;
color: green;
}
.r {
background-image: url('img/refresh2.png');
background-size: contain;
}
.refresh {
outline: none;
width: 50px;
height: 50px;
border-radius: 100%;
position: absolute;
right: 3px;
top: 108px;
opacity: 0;
}
.tree {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px;
position: relative;
}
img {
border-radius: 100%;
width: 150px;
height: 150px;
box-shadow: 8px 8px 13px #222;
border: solid 3px #606f46;
}
<div class="container1">
<div id="no1">
<div class="tree">
<div class="avatar">
<img src="https://entertainment.time.com/wp-content/uploads/sites/3/2013/05/fictioninfluence_list_homersimpson.jpg">
</div>
<button id="btn1" class="refresh r"> </button>
<span id="spn1" class="name">
<input class="name_input" type="text" disabled="true" value="Homer Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
<div class="tree">
<div class="avatar">
<img class="white_bg" src="https://static.wikia.nocookie.net/theultimatesimpsons/images/0/0f/Marge-Simpson-icon.png/revision/latest?cb=20180210061653">
</div>
<button id="btn2" class="refresh r"></button>
<span id="spn2" class="name">
<input class="name_input" type="text" disabled="true" value="Marge Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
</div>
Solution 1:[1]
In the JS, just because you call the variable img doesn't mean that you are working with the image element, you are working with div.tree nodes.
Addendum: per OP "I need the button to not disappear when hovering over the image and then over the button"
Move the buttons inside .avatar and act on the avatar mouse events:
document.querySelectorAll(".tree").forEach(tn => {
let ava = tn.querySelector(".avatar");
let btn = tn.querySelector(".avatar .r");
ava.onmouseover = function() {
btn.style.opacity = 1;
};
ava.onmouseout = function() {
btn.style.opacity = 0;
};
});
#no1 {
display: flex;
justify-content: center;
width: 190px;
line-height: 16px;
margin: auto;
}
.container1 {
width: 580px;
font-family: verdana, arial, helvetica, sans-serif;
font-weight: bold;
font-size: 11px;
text-align: center;
margin: auto;
}
.namefunc {
display: flex;
justify-content: center;
gap: 10px;
}
.name {
background: #beebb3;
border-color: #606f46;
border-radius: 22px 0 22px 0;
padding: 2px;
padding-bottom: 5px;
border-style: solid;
margin-top: 5px;
box-shadow: 4px 4px 13px #222;
width: 145px;
color: green;
}
.name_input {
background: #beebb3;
border: none;
text-align: center;
margin-left: 5px;
margin: 4px;
color: green;
}
.r {
background-image: url('img/refresh2.png');
background-size: contain;
}
.refresh {
outline: none;
width: 50px;
height: 50px;
border-radius: 100%;
position: absolute;
right: 3px;
top: 108px;
opacity: 0;
}
.tree {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px;
position: relative;
}
img {
border-radius: 100%;
width: 150px;
height: 150px;
box-shadow: 8px 8px 13px #222;
border: solid 3px #606f46;
}
<div class="container1">
<div id="no1">
<div class="tree">
<div class="avatar">
<img src="https://entertainment.time.com/wp-content/uploads/sites/3/2013/05/fictioninfluence_list_homersimpson.jpg">
<button id="btn1" class="refresh r"> </button>
</div>
<span id="spn1" class="name">
<input class="name_input" type="text" disabled="true" value="Homer Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
<div class="tree">
<div class="avatar">
<img class="white_bg" src="https://static.wikia.nocookie.net/theultimatesimpsons/images/0/0f/Marge-Simpson-icon.png/revision/latest?cb=20180210061653">
<button id="btn2" class="refresh r"></button>
</div>
<span id="spn2" class="name">
<input class="name_input" type="text" disabled="true" value="Marge Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
</div>
Solution 2:[2]
Your .forEach loop is iterating over your div.tree elements and then adding mouseover and mouseout event handlers to those div elements, rather than looping over the actual img elements within the div.tree elements.
You also should really be using the modern .addEventListener() method to set up event callbacks, which is more powerful than using event properties, such as onmouseover and onmouseout.
document.querySelectorAll(".tree img").forEach(img => {
img.addEventListener("mouseover", function () {
img.closest(".tree").querySelector(".r").style.opacity = 1;
});
img.addEventListener("mouseout", function () {
img.closest(".tree").querySelector(".r").style.opacity = 0;
});
});
#no1 {
display: flex;
justify-content: center;
width: 190px;
line-height: 16px;
margin: auto;
}
.container1 {
width: 580px;
font-family: verdana, arial, helvetica, sans-serif;
font-weight: bold;
font-size: 11px;
text-align: center;
margin: auto;
}
.namefunc {
display: flex;
justify-content: center;
gap: 10px;
}
.name {
background: #beebb3;
border-color: #606f46;
border-radius: 22px 0 22px 0;
padding: 2px;
padding-bottom: 5px;
border-style: solid;
margin-top: 5px;
box-shadow: 4px 4px 13px #222;
width: 145px;
color: green;
}
.name_input {
background: #beebb3;
border: none;
text-align: center;
margin-left: 5px;
margin: 4px;
color: green;
}
.r {
background-image: url('img/refresh2.png');
background-size: contain;
}
.refresh {
outline: none;
width: 50px;
height: 50px;
border-radius: 100%;
position: absolute;
right: 3px;
top: 108px;
opacity: 0;
}
.tree {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px;
position: relative;
}
img {
border-radius: 100%;
width: 150px;
height: 150px;
box-shadow: 8px 8px 13px #222;
border: solid 3px #606f46;
}
<div class="container1">
<div id="no1">
<div class="tree">
<div class="avatar">
<img src="https://entertainment.time.com/wp-content/uploads/sites/3/2013/05/fictioninfluence_list_homersimpson.jpg">
</div>
<button id="btn1" class="refresh r"> </button>
<span id="spn1" class="name">
<input class="name_input" type="text" disabled="true" value="Homer Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
<div class="tree">
<div class="avatar">
<img class="white_bg" src="https://static.wikia.nocookie.net/theultimatesimpsons/images/0/0f/Marge-Simpson-icon.png/revision/latest?cb=20180210061653">
</div>
<button id="btn2" class="refresh r"></button>
<span id="spn2" class="name">
<input class="name_input" type="text" disabled="true" value="Marge Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
</div>
Solution 3:[3]
Use .avatar selector and nextElementSibling to get refresh button
document.querySelectorAll(".tree .avatar").forEach(img => {
img.onmouseover = function () {
let refresh_button = img.nextElementSibling;
refresh_button.style.opacity = 1;
};
img.onmouseout = function () {
let refresh_button = img.nextElementSibling;
refresh_button.style.opacity = 0;
};
});
document.querySelectorAll(".tree .avatar").forEach(img => {
img.onmouseover = function () {
let refresh_button = img.nextElementSibling;
refresh_button.style.opacity = 1;
};
img.onmouseout = function () {
let refresh_button = img.nextElementSibling;
refresh_button.style.opacity = 0;
};
});
#no1 {
display: flex;
justify-content: center;
width: 190px;
line-height: 16px;
margin: auto;
}
.container1 {
width: 580px;
font-family: verdana, arial, helvetica, sans-serif;
font-weight: bold;
font-size: 11px;
text-align: center;
margin: auto;
}
.namefunc {
display: flex;
justify-content: center;
gap: 10px;
}
.name {
background: #beebb3;
border-color: #606f46;
border-radius: 22px 0 22px 0;
padding: 2px;
padding-bottom: 5px;
border-style: solid;
margin-top: 5px;
box-shadow: 4px 4px 13px #222;
width: 145px;
color: green;
}
.name_input {
background: #beebb3;
border: none;
text-align: center;
margin-left: 5px;
margin: 4px;
color: green;
}
.r {
background-image: url('img/refresh2.png');
background-size: contain;
}
.refresh {
outline: none;
width: 50px;
height: 50px;
border-radius: 100%;
position: absolute;
right: 3px;
top: 108px;
opacity: 0;
}
.tree {
display: flex;
flex-direction: column;
align-items: center;
margin: 10px;
position: relative;
}
img {
border-radius: 100%;
width: 150px;
height: 150px;
box-shadow: 8px 8px 13px #222;
border: solid 3px #606f46;
}
<div class="container1">
<div id="no1">
<div class="tree">
<div class="avatar">
<img src="https://entertainment.time.com/wp-content/uploads/sites/3/2013/05/fictioninfluence_list_homersimpson.jpg">
</div>
<button id="btn1" class="refresh r"> </button>
<span id="spn1" class="name">
<input class="name_input" type="text" disabled="true" value="Homer Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
<div class="tree">
<div class="avatar">
<img class="white_bg" src="https://static.wikia.nocookie.net/theultimatesimpsons/images/0/0f/Marge-Simpson-icon.png/revision/latest?cb=20180210061653">
</div>
<button id="btn2" class="refresh r"></button>
<span id="spn2" class="name">
<input class="name_input" type="text" disabled="true" value="Marge Simpson">
<div class="namefunc">
<button class="check">Save</button>
<button class="close">Delete</button>
</div>
</span>
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Siva K V |
