Chris Cummings
Chris Cummings

Reputation: 1548

Affect different element in parent div on hover

When I hover over an <h3> within a <div>, it expands all <ul> elements in all <div> elements with this class.

I'm a bit confused on how to affect only the <ul> within the <div> where I am hovering over the <h3>?

I have HTML structured like this:

jQuery(document).ready(function() {
  jQuery("div.sidemenugroup h3").hover(function() {
    jQuery("div.sidemenugroup ul").slideDown()
  }, function() {
    jQuery("div.sidemenugroup ul").slideUp();
  });
});
div.sidemenugroup ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidemenugroup">
  <h3>Some text</h3>
  <ul>
    <li>List Item 1</li>
    <li>List Item 2</div>
</ul>
</div>
<div class="sidemenugroup">
  <h3>Some other text</h3>
  <ul>
    <li2nd>List Item 1</li>
      <li>2nd List Item 2</div>
</ul>
</div>

Upvotes: 0

Views: 60

Answers (4)

Vucko
Vucko

Reputation: 20834

I agree with showdevs answer, but I also have to say that this can be done with pure CSS:

ul{
    transition: opacity 1s ease-out;
    opacity: 0; 
    height: 0;
    overflow: hidden;
}

h3:hover + ul{
    opacity: 1;
    height: auto;
}
<div class="sidemenugroup">
    <h3>Some text</h3>
    <ul>
        <li>List Item 1</li>
        <li>List Item 2</li>
    </ul>
</div>
<div class="sidemenugroup">
    <h3>Some other text</h3>
    <ul>
        <li>List Item 1</li>
        <li>2nd List Item 2</li>
    </ul>
</div>

And for your slideUp / slideDown animations, you can always use animate.css.

Here's the fiddle

Upvotes: 2

showdev
showdev

Reputation: 29168

Identify the element from which the "hover" event was fired by using JavaScript's "this" keyword.

"When a function is used as an event handler, its this is set to the element the event fired from"

Once you have identified the element that fired "hover" (<h3>), you can traverse from that element to its corresponding <ul>. The way your code is structured, <ul> elements always follow <h3> elements. So, I suggest using jQuery's next(), like so:

jQuery(this).next();

That will select the next element after the "hovered" <h3>, which will be its <ul>. You can then slide that element up or down.

jQuery(document).ready(function() {
  jQuery("div.sidemenugroup h3").hover(function() {
    jQuery(this).next().slideDown()
  }, function() {
    jQuery(this).next().slideUp();
  });
});
div.sidemenugroup ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidemenugroup">
  <h3>Some text</h3>
  <ul>
    <li>List Item 1</li>
    <li>List Item 2</li>
  </ul>
</div>
<div class="sidemenugroup">
  <h3>Some other text</h3>
  <ul>
    <li>List Item 1</li>
    <li>2nd List Item 2</li>
  </ul>
</div>


Refinement

You can simplify your code a bit by making use of jQuery's slideToggle(). Note that hover() will also accept a single function. So, you can trigger the same slide animation when the mouse enters or leaves the element. Use this to toggle the slide state.

The .hover() method, when passed a single function, will execute that handler for both mouseenter and mouseleave events.

Also, to prevent animations from building up in the queue, I recommend adding a stop() before the slide.

See these refinements demonstrated below:

jQuery(document).ready(function() {
  jQuery("div.sidemenugroup h3").hover(function() {
    jQuery(this).next().stop(true, false).slideToggle();
  });
});
div.sidemenugroup ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sidemenugroup">
  <h3>Some text</h3>
  <ul>
    <li>List Item 1</li>
    <li>List Item 2</li>
  </ul>
</div>
<div class="sidemenugroup">
  <h3>Some other text</h3>
  <ul>
    <li>List Item 1</li>
    <li>2nd List Item 2</li>
  </ul>
</div>

Upvotes: 3

Jacob Roberts
Jacob Roberts

Reputation: 1815

This uses next but specifies the element to slide

jQuery(document).ready(function() {
  $("div.sidemenugroup h3").hover(function() {
    $(this).next("div.sidemenugroup ul").slideDown()
  }, function(e) {
    $(this).next("div.sidemenugroup ul").slideUp();
  });
});

Working jsfiddle: https://jsfiddle.net/sk36bru8/

Upvotes: 0

I&#39;m Joe Too
I&#39;m Joe Too

Reputation: 5840

You can use CSS selectors to get the direct child lists of the div:

jQuery( "div.sidemenugroup > ul" ).slideDown()

or use jQuery's children() function:

jQuery( "div.sidemenugroup" ).children( "ul" ).slideDown()

Upvotes: -1

Related Questions