简体   繁体   中英

Javascript mouseover event delegation

I have the following code. How can I affect the status of other links when the cursor is on a link? For example I would like that when the mouse is over a link I can affect the opacity of the other links. I thought of a way to add the event to the link parent nav links and then check if the event is really on the link or outside.

Is the method I started good or I should approach event delegation

 const nav = document.querySelector(".nav__links"); const item = Array.from( document.querySelectorAll(".nav__item")); const link = Array.from( document.querySelectorAll(".nav__link")); link.forEach(t => t.addEventListener('mouseover',function(e){ const targetLink = e.target; console.log(targetLink); if ( t.==targetLink) { t.style.opacity = 0;2; } })) ;
 .nav__links { display: flex; align-items: center; list-style: none; justify-content:center; }.nav__item { margin-left: 0.7rem; }
 <ul class="nav__links"> <li class="nav__item"> <a class="nav__link" href="#">Home</a> </li> <li class="nav__item"> <a class="nav__link" href="#">About</a> </li> <li class="nav__item"> <a class="nav__link" href="#">Testimonials</a> </li>

If you're okay with dimming the options when the mouse is over the nav list and then not dimming the active one, you can do this just with CSS (I added a bit of transition to it, but you can remove that):

.nav__links:hover li {
    opacity: 0.2;
    transition: opacity 0.1s;
}
.nav__links:hover li:hover {
    opacity: 1;
}

Live Example:

 .nav__links { display: flex; align-items: center; list-style: none; justify-content: center; }.nav__links:hover li { opacity: 0.2; transition: opacity 0.1s; }.nav__links:hover li:hover { opacity: 1; }.nav__item { margin-left: 0.7rem; }
 <ul class="nav__links"> <li class="nav__item"> <a class="nav__link" href="#">Home</a> </li> <li class="nav__item"> <a class="nav__link" href="#">About</a> </li> <li class="nav__item"> <a class="nav__link" href="#">Testimonials</a> </li> </ul>

That also has the advantage that there's no flashing as you move the mouse across from one nav item to the next (going out of one li , over the ul , then into the next li ).

But if you only want them dimmed when one of the nav items is hovered, I don't think we can do it just with CSS because there's no general sibling combinator (there's just the next sibling [ + ] or subsequent sibling [ ~ ]).

But we can let CSS do most of the work. The trick is making sure that we un-dim things when the mouse is no longer over any of the nav items. Remember that the mouse can jump out of elements (for instance, if the user Alt+Tab s to a different app, moves the mouse, and then tabs back to the page), so we have to be fairly aggressive about un-dimming things.

Here's a version that uses a passive mousemove handler on the document . Normally I'd avoid a mousemove handler on document since it will get fired a lot , but what we're doing inside the handler is really quick:

document.addEventListener("mouseover", event => {
    const li = event.target.closest(".nav__links li");
    if (li) {
        nav.classList.add("dimmed");
    } else {
        nav.classList.remove("dimmed");
    }
}, {passive: true});

Then we throw some CSS at it:

.nav__links.dimmed li {
    opacity: 0.2;
    transition: opacity 0.1s;
}
.nav__links.dimmed li:hover {
    opacity: 1;
}

Live Example:

 const nav = document.querySelector(".nav__links"); document.addEventListener("mouseover", event => { const li = event.target.closest(".nav__links li"); if (li) { nav.classList.add("dimmed"); } else { nav.classList.remove("dimmed"); } }, {passive: true});
 .nav__links { display: flex; align-items: center; list-style: none; justify-content: center; }.nav__links.dimmed li { opacity: 0.2; transition: opacity 0.1s; }.nav__links.dimmed li:hover { opacity: 1; }.nav__item { margin-left: 0.7rem; }
 <ul class="nav__links"> <li class="nav__item"> <a class="nav__link" href="#">Home</a> </li> <li class="nav__item"> <a class="nav__link" href="#">About</a> </li> <li class="nav__item"> <a class="nav__link" href="#">Testimonials</a> </li> </ul>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM