You can use CSS to add and remove the hover. Basic code showing that and added code to toggle active so it can move around.
const menu = document.querySelector(".main-container")
menu.addEventListener("click", function (evt) {
const item = evt.target.closest(".item")
if (item) {
menu.querySelector(".item.active").classList.remove("active")
item.classList.add("active")
}
});
.main-container .item.active {
background-color: green;
}
.item,
.main-container:hover .item.active {
background-color: yellow;
transition: background-color .3s;
}
.main-container:hover .item:hover {
background-color: lime;
transition: background-color .3s;
}
<div class="main-container">
<div class="item active">
<a href="#">item 1</a>
</div>
<div class="item">
<a href="#">item 2</a>
</div>
<div class="item">
<a href="#">item 3</a>
</div>
</div>
You don’t need JS for that.
Just overwrite style when the container is hovered
.main-container:hover .item.hover {
background-color: transparent;
}
.item.hover {
background-color: red;
}
.item:hover {
background-color: red !important;
}
<div class="main-container" >
<div class="item hover">
<a href="#">item 1</a>
</div>
<div class="item">
<a href="#">item 2</a>
</div>
<div class="item">
<a href="#">item 3</a>
</div>
</div>
See jsfiddle: https://jsfiddle.net/hs2yfxm1/
If you’re trying to style this based on a hover event you should be utilizing the proper pseudo-class. You mentioned that you always want the first item to be “active”, why not set an .active
class that matches the format styling of :hover
? For example:
SCSS
.item {
border-color: red;
&.active,
&:hover {
border-color: blue;
}
}
CSS
.item {
border-color: red;
}
.item.active,
.item:hover {
border-color: blue;
}
Note: In general, it’s best practice to limit your use of JS whenever possible. If something is attainable simply with HTML and CSS, that should be the preferred implementation in most cases.
Other than the stylistic portion, just one comment on your JS. In your example, you’re utilizing e.target
this can be dangerous if the element has children in that the target could be the child. Since you’re targeting each element individually (a lot of event listeners that you may want to consider re-working) you can make use of e.currentTarget
for other JS needs.
Is this what you are after?
.active { background-color:grey; }
.item:hover { background-color:yellow; }
<div class="main-container" >
<div class="item active">
<a href="#">item 1</a>
</div>
<div class="item">
<a href="#">item 2</a>
</div>
<div class="item">
<a href="#">item 3</a>
</div>
</div>
I have a structure like below and I want to toggle active
the currently hovered .item
element.
I’m using a simple Vanilla JavaScript function that I usually use for click-like situations and it works.
function myFunction(e) {
var elems = document.querySelectorAll(".hover");
[].forEach.call(elems, function(el) {
el.classList.remove("hover");
});
e.target.classList.add("hover");
}
<div class="main-container">
<div class="item hover" onmouseover="myFunction(event)">
<a href="#">item 1</a>
</div>
<div class="item" onmouseover="myFunction(event)">
<a href="#">item 2</a>
</div>
<div class="item" onmouseover="myFunction(event)">
<a href="#">item 3</a>
</div>
</div>
So far so good, but here comes the tricky part. When the mouse goes to a sibling element the hover correctly is changing to the inner one.
I tried some CSS ticks but I can’t manage to make it work, any thoughts would be much appreciated
P.S. I prefer Vanilla JavaScript than jQuery
That’s because I want to always have the first element active even if it’s not hovered and when the mouse leave the section make it active again
That is correct I can’t believe i missed it! I also have a lot of inner element’s depending on the hover but think I will manage to make it work that way, Thanks
Does it allow to stack css selectors like that? Or you just post SCSS or something other like that?
Not yet, I believe. That was just SCSS. Updated to have both versions.
You totally have a point there, I think something like that. I have a lot of inner elements depending on the hover so I will try with an active class an overrides for the hover. Thanks