4

Not really sure how to phrase that in the title. Anyways, what I'm saying is that I have three divs with the same class name. I want to add a mouseover function that only works on the select div, not all of them at once. For example :(https://jsfiddle.net/1y2jw2y0/) this makes all the divs show/hide, I only want the selected one to act on the jQuery function.

Html:

<div class="box">
  <p class="show">Show</p>
  <p class="hide">hide</p>
</div>

<div class="box">
  <p class="show">Show</p>
  <p class="hide">hide</p>
</div>

<div class="box">
  <p class="show">Show</p>
  <p class="hide">hide</p>
</div>

Css:

.box {
  display: inline-block;
  width: 150px;
  height: 150px;
  border: 1px solid #000;
}

.hide {
  display: none;
}

jQuery:

$(document).ready(function() {
  $('.box').mouseover(function() {
    $('.hide').show();
    $('.show').hide();
  });
  $('.box').mouseleave(function() {
    $('.hide').hide();
    $('.show').show();
  });
});
kenny
  • 438
  • 4
  • 14

6 Answers6

3

Use this to target the "selected" element, then select the child with find() or children():

$(document).ready(function() {
  $('.box').mouseover(function() {
    $(this).children('.hide').show();
    $(this).children('.show').hide();
  });
  $('.box').mouseleave(function() {
    $(this).children('.hide').hide();
    $(this).children('.show').show();
  });
});

JSFiddle Demo

Edited, to outline the performance issues brought up:

For basic details about the difference between find and children, this answer is a good resource.

In this case, I found .find() to be faster as a whole, usually ~.2ms.

After extensive testing, It appears there is very little, or no difference between using find(), or using $('.selector', this)

Overall, the results were similar. In some cases, it appears $('.selector', this) is slower, in others find().

However, find does give you extra functionality that cannot be achieved with $('.selector', this), such as a direct child selector: .selector > .anotherone, or caching the jQuery object to save resources.

Summary: There isn't much difference, it all depends on your case, and what you prefer.

Community
  • 1
  • 1
Jacob G
  • 13,762
  • 3
  • 47
  • 67
  • This is perfect. I'll accept this once it allows me to. Thank you! – kenny Jun 28 '16 at 01:56
  • 1
    @Jacob, Isn't find(), children() are slow comparing to direct selector $('.selector', this) ? Those are calling another jquery API if i'm not wrong. – Jerad Rutnam Jun 28 '16 at 02:01
  • 1
    @JeradRutnam For this specific case, then a definite *maybe*. I profiled both functions, and the results were close, within a fraction of a millisecond, usually with the "direct select" coming out about 1/10 to 2/10 of a millisecond faster. However, using `children` or `find` allows more diversity in your selector, such as selecting only direct children of the element. – Jacob G Jun 28 '16 at 02:47
  • @JacobGray, The same thing happening to me. could you tell me, the sandbox link- https://codesandbox.io/s/modest-lamport-9x4l6, https://9x4l6.csb.app/ – vishal Jan 21 '22 at 14:58
3

You can do it all in CSS:

.box:hover .hide {
  display: block;
}

.box:hover .show {
  display: none;
}

Example: http://jsfiddle.net/Zy2Ny/

If you really want to do it in JavaScript, simply use $(this) and find():

More information about whether children() or find() is faster.

$(".box").mouseover(function() {
    $(this).find(".hide").show();
    $(this).find(".show").hide();
});

$(".box").mouseleave(function() {
    $(this).find(".hide").hide();
    $(this).find(".show").show();
});
.box {
  display: inline-block;
  width: 150px;
  height: 150px;
  border: 1px solid #000;
}

.hide {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="boxes">

  <div class="box">
    <p class="show">Show</p>
    <p class="hide">Hide</p>
  </div>

  <div class="box">
    <p class="show">Show</p>
    <p class="hide">Hide</p>
  </div>

  <div class="box">
    <p class="show">Show</p>
    <p class="hide">Hide</p>
  </div>
  
</div>

Example: https://jsfiddle.net/1y2jw2y0/5/

Community
  • 1
  • 1
gotnull
  • 26,454
  • 22
  • 137
  • 203
2

Add a 'this' along with the selector,

$(document).ready(function() {
    $('.box').mouseover(function() {
        $('.hide', this).show();
        $('.show', this).hide();
    });
    $('.box').mouseleave(function() {
        $('.hide', this).hide();
        $('.show', this).show();
    });
});

Example: https://jsfiddle.net/1y2jw2y0/6/

So basically you have to select the child selector of the mouse hovered element instead.

NOTE:- You can do this using find() & children() jquery API's as well. But it's bit slower than selecting directly.

And why not doing with pure css? See the example below,

.box {
   display: inline-block;
   width: 150px;
   height: 150px;
   border: 1px solid #000;
}
.hide,
.box:hover > .show {
   display: none;
}
.box:hover > .hide {
   display: block;
}

Example: https://jsfiddle.net/1y2jw2y0/3/

Jerad Rutnam
  • 1,536
  • 1
  • 14
  • 29
0

Change your syntax to

$('.box').mouseover(function() { $(this).find('.hide').show(); $(this).find('.show').hide(); });

Just navigate from the current element which trigerred the event to its child elements using $(this)

Rajshekar Reddy
  • 18,647
  • 3
  • 40
  • 59
0

The problem is that your selector is targeting all of the divs with that class name in the document. You need to limit the scope to just the divs inside of the box you care about. One way to do this would be

$(this).find('.hide').show()

Instead of

$(".hide").show();

See here https://jsfiddle.net/1y2jw2y0/1/

John Ackerman
  • 1,041
  • 1
  • 9
  • 16
0

You can see: $('.box') select all .box div. So that $('.hide') select all .hide p => when you click on a box, all .hide p are affected. You can fix as following code:

$(this).select('.hide').hide()
$(this).select('.show').show()
Jeffrey04
  • 6,138
  • 12
  • 45
  • 68
tavsta
  • 11
  • 3