Tom
Tom

Reputation: 101

Stop hover() effect applying to every div

Basically, what I am trying to achieve is that when I hover on the div which have a class of rectangle, it should display the div which has a class of description. In the beginning, the description display value will be "none". But When I hover it on the div, it should show up.

var $projectOneHtml = $(".hTML-1")
var $projectTwoHtml = $(".hTML-2")
var $projectThreeHtml = $(".hTML-3")

function myName(x) {
  $(x).hover(function() {
    $(".description").show();
    $(this).addClass("hover");
  }, function() {
    $(".description").hide();
    $(this).removeClass("hover");
  })
};

myName($projectOneHtml);
myName($projectTwoHtml);
myName($projectThreeHtml);
.description {
  background-color: white;
  border: 1px solid white;
  width: 354px;
  height: 300px;
  text-align: center;
  color: black;
  font-size: 18px;
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="projects">
  <div class="rectangle hTML-1">
    <img src="Projects/card.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle hTML-2">
    <img src="Projects/clock.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle hTML-3">
    <img src="Projects/canvas.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>
</div>

The question is: when I hover, it affects the three divs. What I want is when I hover the first div, it should display the description div. Not the other divs at the same time. Hope that makes sense. I appreciate everyone's time.

Upvotes: 1

Views: 439

Answers (2)

Martin
Martin

Reputation: 16423

I personally would favour a CSS-only approach to this without the effort of using JS at all.

In this case, using this CSS will display the .description only when it's parent is hovered:

div.rectangle:hover > .description {
  display: block;
}

This can be seen working in the snippet below which has no JS:

.description {
  background-color: white;
  border: 1px solid white;
  width: 354px;
  height: 300px;
  text-align: center;
  color: black;
  font-size: 18px;
  display: none;
}

div.rectangle:hover > .description {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="projects">
  <div class="rectangle hTML-1">
    <img src="//via.placeholder.com/354x180" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle hTML-2">
    <img src="//via.placeholder.com/354x180" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle hTML-3">
    <img src="//via.placeholder.com/354x180" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>
</div>

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337560

The issue is because you're selecting every .description element in the DOM when the mouseenter/mouseleave events fire. To fix this, use find() from the element that raised the event to only affect the children of that element.

Also note that I removed the use of incremental classnames. This is an anti-pattern which completely negates the purpose of classes in the first place; that is to group elements by common behaviour.

$('.rectangle').hover(function() {
  $(this).addClass('hover').find(".description").show();
}, function() {
  $(this).removeClass("hover").find('.description').hide();
});
.description {
  background-color: white;
  border: 1px solid white;
  width: 354px;
  height: 300px;
  text-align: center;
  color: black;
  font-size: 18px;
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="projects">
  <div class="rectangle">
    <img src="Projects/card.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle">
    <img src="Projects/clock.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle">
    <img src="Projects/canvas.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>
</div>

That being said, it's much better practice to create this kind of logic using CSS alone as it performs far better than JS. Try this alternative:

.description {
  background-color: white;
  border: 1px solid white;
  width: 354px;
  height: 300px;
  text-align: center;
  color: black;
  font-size: 18px;
  display: none;
}

.rectangle:hover .description {
  display: block;
}
<div class="projects">
  <div class="rectangle">
    <img src="Projects/card.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle">
    <img src="Projects/clock.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>

  <div class="rectangle">
    <img src="Projects/canvas.jpg" width="354px" height="180px">
    <div class="description">
      <p>A simple business card was created by HTML and CSS.</p>
    </div>
  </div>
</div>

Upvotes: 2

Related Questions