Home > Software design >  Add class to closest element of e.target
Add class to closest element of e.target

Time:12-23

I'm trying to add a shake effect to a font-awesome icon whenever hovering over the hyperlink beside it. The HTML looks like this:

<div >
        <span>
                <i ></i>
        </span>
        <span>
                <a href="tel:XXXX XX XX XX">John: XXXX XX XX XX</a>
        </span>
</div>

I'm trying to add the class fa-shake to the matching i with class "fas", and remove it when not hovering.

I'm not super well versed in jQuery, but I read a lot of the documentation and other stackoverflow articles getting this to work, to no avail.

My current code is:

$(document).ready(function() {

        $(".icon-hyperlink a").hover(function(e) {
                e.target.closest(".fas").addClass("fa-shake");
        }, function(e) {
                e.target.closest(".fas").removeClass("fa-shake");     
        });

  });

The error I'm getting is:

Uncaught TypeError: Cannot read properties of null (reading 'addClass')

I also tried the following:

$(e.target.closest(".fas")).addClass("fa-shake");

That gives me no errors, but it also doesn't work.

CodePudding user response:

You need to traverse up to a shared parent, then find the icon

$(".icon-hyperlink a").hover(
  function () {
    $(this).closest(".icon-hyperlink").find(".fas").addClass("fa-shake");
  },
  function () {
    $(this).closest(".icon-hyperlink").find(".fas").removeClass("fa-shake");
  }
);

As mentioned above, the <span> elements seem unnecessary and just complicate the matter.

Also, it's 2022 and you probably don't need jQuery.

document.addEventListener("mouseenter", (e) => {
  if (e.target.matches(".icon-hyperlink a")) {
    e.target
      .closest(".icon-hyperlink")
      .querySelector(".fas")
      ?.classList.add("fa-shake");
  }
});

document.addEventListener("mouseleave", (e) => {
  if (e.target.matches(".icon-hyperlink a")) {
    e.target
      .closest(".icon-hyperlink")
      .querySelector(".fas")
      ?.classList.remove("fa-shake");
  }
});

CodePudding user response:

You can use .parents() and .find() instead to select the .fas element you're trying to find.

Just ignore the html and css changes I made, they're only there to demonstrate the js. Instead of shaking, the .fas element turns red.

$(document).ready(function() {

        $(".icon-hyperlink a").hover(function(e) {
                $(e.target).parents(".icon-hyperlink").find(".fas").addClass("fa-shake");
        }, function(e) {
                $(e.target).parents(".icon-hyperlink").find(".fas").removeClass("fa-shake");     
        });

  });
.fa-shake {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
        <span>
                <i >Icon</i>
        </span>
        <span>
                <a href="tel:XXXX XX XX XX">John: XXXX XX XX XX</a>
        </span>
</div>

CodePudding user response:

This can be achieved with no javascript and a little detective work of what FA uses behind the scenes.

.phone::before{
  font-family: "Font Awesome 6 Free";
  content: "\f095";
  display:inline-block;
  font-weight:900;
  color:black;
  margin-right:0.25em;  
}

.phone:hover::before{
  animation-name: fa-shake;
  animation-duration: var(--fa-animation-duration,1s);
  animation-iteration-count: var(--fa-animation-iteration-count,infinite);
  animation-timing-function: var(--fa-animation-timing,linear);
  animation-delay: var(--fa-animation-delay,0s);
  animation-direction: var(--fa-animation-direction,normal);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8 y gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>


<div >
  <a href="tel:XXXX XX XX XX" >John: XXXX XX XX XX</a>
</div>

  • Related