简体   繁体   中英

Change the style on hover for any element without changing the parent's style

I need to add css class .hovered on html element when hover, for this I created a small example snippet below. It has couple of issues.

When I hover on a child element it shouldn't add .hovered class to its parents, for example in below snippet, a inside nav element, it shouldn't add border to it's parent ( nav ).

But most importantly, I need to select elements in DOM dynamically, so instead this $( "div,nav,h1,h5,p,a,button") I would like to provide something like $( "*") , so I would be able to hover on any kind of element.

 $(document).ready(function(){ $( "div,nav,h1,h5,p,a,button") .mouseenter(function() { $( this ).addClass("hovered"); }) .mouseleave(function() { $( this ).removeClass("hovered"); }); });
 .hovered { border: 2px solid red; cursor: pointer; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"/> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm"> <h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5> <nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="#">Features</a> <a class="p-2 text-dark" href="#">Enterprise</a> <a class="p-2 text-dark" href="#">Support</a> <a class="p-2 text-dark" href="#">Pricing</a> </nav> <button>Sign up</button> </div> <div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center"> <h1 class="display-4">Title</h1> <p class="lead">paragrpah</p> </div>

How could I achieve it with vanilla JavaScript or jQuery?

I'm not sure how efficient doing what you want can be, as you want to run this for every element on every mouse action. But if you really want to, you can do it like this:

$("*").not("body,html")
   .mouseenter(function() {
        e.stopPropagation();
        $(this).addClass("hovered");
        $(this).parent().removeClass("hovered");
    })
    .mouseleave(function() {
        $(this).removeClass("hovered");
    });
});

How this works:

  • Select all elements except body and html
  • On mouse over of an element: Add the class to the hovered element and Remove the class from the parent element

Remember that when an element is hovered, it's parent (and its parent's parent etc) are also hovered, so this is why we need to remove the class from the parent.

Working Example:

 $(document).ready(function() { $("*").not("body,html") .mouseenter(function() { console.log($(this)); $(this).addClass("hovered"); $(this).parent().removeClass("hovered"); }) .mouseleave(function() { $(this).removeClass("hovered"); }); });
 .hovered { border: 2px solid red; cursor: pointer; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" /> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm"> <h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5> <nav class="my-2 my-md-0 mr-md-3 p-2"> <a class="p-2 text-dark" href="#">Features</a><a class="p-2 text-dark" href="#">Enterprise</a><a class="p-2 text-dark" href="#">Support</a><a class="p-2 text-dark" href="#">Pricing</a> </nav> <button>Sign up</button> </div> <div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center"> <h1 class="display-4">Title</h1> <p class="lead">paragrpah</p> </div>

Update : The 2 issues you mention are to do with your HTML. You can fix them as follows:

  1. Hovering a menu item outside the text can also outline the nav :
    Your nav element isn't fully containing your menu items - they are extending outside the nav boundary because you added p-2 to them. Adding p-2 to the nav will make the hover work as expected.
  2. Nothing is outlined when hovering between menu items :
    White space doesn't trigger a hover event , and your a elements are separated with white space (a linebreak, tab or space will do this). You can delete the white space from between the a elements like this - it's a bit of a hack but it works:
     <a href="#">Option 1</a><a class=href="#">Option 2</a>...

These are fixed in the working example above if you try it now

In Javascript you could do something like below:

You can get element by there tagName's(like div, h1) and get them by getElementsByTagName or you can add classes to these element and get by getElementsByClassName

document.addEventListener('DOMContentLoaded',  function () {
   document.getElementsByTagName('div')[0].addEventListener("mouseover", 
     function(e) {
        e.target.classList.add("hovered");
   });
    
   document.getElementsByTagName('div')[0].addEventListener("mouseout", 
   function(e) 
    { 
        e.target.classList.remove("hovered");
    });
});

You probably don't need Js here.

CSS-only solution:

 div:hover, div *:hover { border: 2px solid red; cursor: pointer; }
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"/> <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm"> <h5 class="my-0 mr-md-auto font-weight-normal">Company name</h5> <nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="#">Features</a> <a class="p-2 text-dark" href="#">Enterprise</a> <a class="p-2 text-dark" href="#">Support</a> <a class="p-2 text-dark" href="#">Pricing</a> </nav> <button>Sign up</button> </div> <div class="pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center"> <h1 class="display-4">Title</h1> <p class="lead">paragrpah</p> </div>

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