YTZ
YTZ

Reputation: 938

Vertical scroll div on mouseover

I want to let a div scroll vertically (downwards) when the user mouseovers it, and let it scroll back to the top of the div on mouseout.

$(".content").on('mouseover', '.description', function() {
  if ($(this).hasClass('scrolling')) return;
  console.log('in');
  var maxscroll = $(this)[0].scrollHeight
  $(this).animate({
    scrollTop: maxscroll
  }, 450);
});

$(".content").on('mouseout', '.description', function() {
  $(this).stop();
  console.log('out');
  $(this).addClass('scrolling');
  $(this).animate({
    scrollTop: 0
  }, 425, "linear", function() {
    $(this).removeClass('scrolling')
  });
});
.content {
  height: 70px;
  width: 300px;
  overflow-y: scroll;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.content::-webkit-scrollbar {
  width: 0;
  height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
  <div class="content">
    <div class="description">
      Lorem ipsum dolor sit amet, consectetr adipiscing elit. Fusce eget turpis a tortor porttitor eleifend. Phasellus tincidunt commodo purus non pellentesque. Nam a turpis magna. Vestibulum quis erat at dolor bibendum auctor in mattis orci. Etiam vehicula
      est at metus tempor, sit amet cursus velit bibendum. Sed varius sapien metus, non convallis sem scelerisque at. Nam ac elementum turpis, vel interdum turpis. Nunc et blandit lacus. Donec pellentesque dictum quam, non varius dui. Mauris elit eros,
      ultrices non justo at, auctor ornare nibh. Nam vehicula elit at ipsum placerat, nec dictum ex scelerisque. Pellentesque laoreet iaculis odio, id posuere risus.
    </div>
  </div>
</div>

I think I'm close, but I haven't figured out why it isn't scrolling yet.

Upvotes: 0

Views: 697

Answers (1)

Terry
Terry

Reputation: 66113

This is because the $(this) in your event listener callbacks is not referring to the scrollable .content element, but refers to .description instead. There is really no need listen to the mouseover/mouseout evens bubbling up from .description up to .content. You can simply do this:

$(".content").on('mouseover', function() { ... }
$(".content").on('mouseout', function() { ... }

...and the $(this) will refer to the actual .content element and it will scroll as expected. See proof-of-concept below:

$(".content").on('mouseover', function() {
  if ($(this).hasClass('scrolling')) return;
  var maxscroll = $(this)[0].scrollHeight
  $(this).animate({
    scrollTop: maxscroll
  }, 450);
});

$(".content").on('mouseout', function() {
  $(this).stop();
  $(this).addClass('scrolling');
  $(this).animate({
    scrollTop: 0
  }, 425, "linear", function() {
    $(this).removeClass('scrolling')
  });
});
.content {
  height: 70px;
  width: 300px;
  overflow-y: scroll;
  scrollbar-width: none;
  -ms-overflow-style: none;
  background-color: #ccc;
}

.content::-webkit-scrollbar {
  width: 0;
  height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
  <div class="content">
    <div class="description">
      Lorem ipsum dolor sit amet, consectetr adipiscing elit. Fusce eget turpis a tortor porttitor eleifend. Phasellus tincidunt commodo purus non pellentesque. Nam a turpis magna. Vestibulum quis erat at dolor bibendum auctor in mattis orci. Etiam vehicula
      est at metus tempor, sit amet cursus velit bibendum. Sed varius sapien metus, non convallis sem scelerisque at. Nam ac elementum turpis, vel interdum turpis. Nunc et blandit lacus. Donec pellentesque dictum quam, non varius dui. Mauris elit eros,
      ultrices non justo at, auctor ornare nibh. Nam vehicula elit at ipsum placerat, nec dictum ex scelerisque. Pellentesque laoreet iaculis odio, id posuere risus.
    </div>
  </div>
</div>

However, if you really should insist on binding the mouseover/mouseout events to the nested .description element, then you will need to swap all the $(this) references to $(this).closest('.content'):

$(".content").on('mouseover', '.description', function() {
  var $content = $(this).closest('.content');
  if ($content.hasClass('scrolling')) return;
  var maxscroll = $(this)[0].scrollHeight
  $content.animate({
    scrollTop: maxscroll
  }, 450);
});

$(".content").on('mouseout', '.description', function() {
  var $content = $(this).closest('.content');
  $content.stop();
  $content.addClass('scrolling');
  $content.animate({
    scrollTop: 0
  }, 425, "linear", function() {
    $content.removeClass('scrolling')
  });
});
.content {
  height: 70px;
  width: 300px;
  overflow-y: scroll;
  scrollbar-width: none;
  -ms-overflow-style: none;
  background-color: #ccc;
}

.content::-webkit-scrollbar {
  width: 0;
  height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
  <div class="content">
    <div class="description">
      Lorem ipsum dolor sit amet, consectetr adipiscing elit. Fusce eget turpis a tortor porttitor eleifend. Phasellus tincidunt commodo purus non pellentesque. Nam a turpis magna. Vestibulum quis erat at dolor bibendum auctor in mattis orci. Etiam vehicula
      est at metus tempor, sit amet cursus velit bibendum. Sed varius sapien metus, non convallis sem scelerisque at. Nam ac elementum turpis, vel interdum turpis. Nunc et blandit lacus. Donec pellentesque dictum quam, non varius dui. Mauris elit eros,
      ultrices non justo at, auctor ornare nibh. Nam vehicula elit at ipsum placerat, nec dictum ex scelerisque. Pellentesque laoreet iaculis odio, id posuere risus.
    </div>
  </div>
</div>

Upvotes: 2

Related Questions