AndrewLeonardi
AndrewLeonardi

Reputation: 3512

Scroll down using Jquery - On Hover

Goal: On hover - scroll down within a div. When the hover stops - stop scrolling within div. This is what I've tried. This works except it only hovers down 150px every time the mouse hovers over #down1. So it's not continuous. Any ideas?

hovered = false;

$("#down1").on({
  mouseenter: function() {
    hover = true;
    if (hover = true) {
      var y = $('#avoidOptions').scrollTop(); //your current y position on the page
      $('#avoidOptions').scrollTop(y + 150);
    }
  },
  mouseleave: function() {
    hover = false;
  }
});
.scrollingOptions {
  height: 30vh;
  width: 100%;
  overflow: auto;
  z-index: 1000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class='scrollingOptions' id='avoidOptions'>
  <p class='likeavoid avoid1'>1
  </p>
  <p class='likeavoid avoid2'>2
  </p>
  <p class='likeavoid avoid3'>3
  </p>
  <p class='likeavoid avoid4'>4
  </p>
  <p class='likeavoid avoid5'>5
  </p>
  <p class='likeavoid avoid6'>6
  </p>
  <p class='likeavoid avoid7'>7
  </p>
  <p class='likeavoid avoid8'>8
  </p>
  <p class='likeavoid avoid9'>9
  </p>
  <p class='likeavoid avoid10'>10
  </p>
  <p class='likeavoid avoid11'>11
  </p>
  <br>
</div>
<p class='white text-center' id='down1'> Scroll Down - Hover Here</p>

Upvotes: 0

Views: 1485

Answers (4)

Mark Schultheiss
Mark Schultheiss

Reputation: 34158

Question specific:

If you set an interval to scroll it will continue to fire until you move the mouse off when you can clear that interval using the id that the function returns.

You have if (hover = true) { which should be if (hover === true) { or since it is a boolean simply use that if (hover) { although I do not see a reason to have it for use here.

Note "this" here this.intervalId is the element with #down1 but it works here since we have it in both event handlers, it might be better to use a namespace like var myApp ={intervalId:null,scrollElement:function(scrollTarget, scrollBy) {}}; referenced as myApp.intervalId for that and the called function (and not a global like var intervalId; for example)

Optional:

You can also create a function as I illustrate and call it passing parameters, you might even then be able to reuse that function.


Observations:

  • I am not a fan of <br /> just to add space so I removed it and added padding at the bottom to the parent instead
  • Rather than <p></p> consider a <div> with margin or padding to space things
  • I noted you have a bunch of numbered classes. If you target them for some reason, OK but instead you can also detect the index of an element like for example jQuery has a 0 based index such as $('.likeavoid').index(); or if you know the index value $('.likeavoid').eq(5); to target one
  • I added an example of storing an interval value in the element markup, if you extend that to all of the values you could then use the same events for more than one element grouping.
  • You could also smooth the scroll by reference: Smooth scrolling when clicking an anchor link

function scrollElement(scrollTarget, scrollBy) {
  scrollTarget.scrollTop(scrollTarget.scrollTop() + scrollBy);
}
$("#down1").on({
  mouseenter: function(event) {
    // these could also be stored on event.target like I did for the interval
    let scrollAmount = 150; //amount could be stored
    let scrollTarget = $('#avoidOptions'); //id could be stored
    let timeInterval = $(event.target).data("scroll-interval");
    this.intervalId = window.setInterval(scrollElement, timeInterval, scrollTarget, scrollAmount);
  },
  mouseleave: function(event) {
    window.clearInterval(this.intervalId);
  }
});
.scrollingOptions {
  height: 30vh;
  width: 100%;
  overflow: auto;
  z-index: 1000;
  padding-bottom: 1em;
}

.scroller {
  border: solid 1px #EEEEEE;
  background-color: #eeffff;
  margin-top: 1em;
}

.likeavoid {
  border: dashed 1px #EEEEEE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class='scrollingOptions' id='avoidOptions'>
  <p class='likeavoid avoid1'>1</p>
  <p class='likeavoid avoid2'>2</p>
  <p class='likeavoid avoid3'>3</p>
  <p class='likeavoid avoid4'>4</p>
  <p class='likeavoid avoid5'>5</p>
  <p class='likeavoid avoid6'>6</p>
  <p class='likeavoid avoid7'>7</p>
  <p class='likeavoid avoid8'>8</p>
  <p class='likeavoid avoid9'>9</p>
  <p class='likeavoid avoid10'>10</p>
  <p class='likeavoid avoid11'>11</p>
</div>
<div class='scroller white text-center' id='down1' data-scroll-interval="1000"> Scroll Down - Hover Here</div>

UNTESTED on mobile device: per comment option react on mobile per spec properly. reference https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent

function scrollElement(scrollTarget, scrollBy) {
  scrollTarget.scrollTop(scrollTarget.scrollTop() + scrollBy);
}

function enterHandler(event) {
  // these could also be stored on event.target like I did for the interval
  let scrollAmount = 150; //amount could be stored
  let scrollTarget = $('#avoidOptions'); //id could be stored
  let timeInterval = $(event.target).data("scroll-interval");
  this.intervalId = window.setInterval(scrollElement, timeInterval, scrollTarget, scrollAmount);
  event.preventDefault();
}

function leaveHandler(event) {
  window.clearInterval(this.intervalId);
  event.preventDefault();
}
$("#down1")
  .on('touchstart', enterHandler).on('touchend', leaveHandler)
  .on('mouseenter', enterHandler).on('mouseleave', leaveHandler);
.scrollingOptions {
  height: 30vh;
  width: 100%;
  overflow: auto;
  z-index: 1000;
  padding-bottom: 1em;
}

.scroller {
  border: solid 1px #EEEEEE;
  background-color: #eeffff;
  margin-top: 1em;
}

.likeavoid {
  border: dashed 1px #EEEEEE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class='scrollingOptions' id='avoidOptions'>
  <p class='likeavoid avoid1'>1</p>
  <p class='likeavoid avoid2'>2</p>
  <p class='likeavoid avoid3'>3</p>
  <p class='likeavoid avoid4'>4</p>
  <p class='likeavoid avoid5'>5</p>
  <p class='likeavoid avoid6'>6</p>
  <p class='likeavoid avoid7'>7</p>
  <p class='likeavoid avoid8'>8</p>
  <p class='likeavoid avoid9'>9</p>
  <p class='likeavoid avoid10'>10</p>
  <p class='likeavoid avoid11'>11</p>
</div>
<div class='scroller white text-center' id='down1' data-scroll-interval="1000"> Scroll Down - Hover Here</div>

Upvotes: 2

Svdb
Svdb

Reputation: 367

You can probably do this with a short interval timer

window.setInterval(function(){
  /// call your function here
}, 500);

To stop the timer you can use

clearInterval()

It should look something like this

var scroll;

$("#down1").on({
  mouseenter: function() {
      scroll = window.setInterval(function() {
          var y = $('#avoidOptions').scrollTop();
          $('#avoidOptions').scrollTop(y + 150);
      }, 500);
    }
  },
  mouseleave: function() {
    clearInterval(scroll);
  }
});

Upvotes: 0

nilan0
nilan0

Reputation: 21

An interval timer worked for me:

$("#down1").on({
  mouseenter: function() {
    this.timer = setInterval(function() {
        var y = $('#avoidOptions').scrollTop();  //your current y position on the page
        $('#avoidOptions').scrollTop(y + 150);
    }, 500);
  },
  mouseleave: function() {
    clearInterval(this.timer);
  }
});

setInterval starts the timer, and the function runs after 500 ms and then repeats. Stops with clearInterval. Also, checking if hover is true immediately after setting it to true is unnecessary. I removed that part.

Demo: https://jsfiddle.net/4vco2arg/

$("#down1").on({
  mouseenter: function() {
    this.timer = setInterval(function() {
      var y = $('#avoidOptions').scrollTop(); //your current y position on the page
      $('#avoidOptions').scrollTop(y + 150);
    }, 500);
  },
  mouseleave: function() {
    clearInterval(this.timer);
  }
});
.scrollingOptions {
  height: 30vh;
  width: 100%;
  overflow: auto;
  z-index: 1000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='scrollingOptions' id='avoidOptions'>
  <p class='likeavoid avoid1'>1
  </p>
  <p class='likeavoid avoid2'>2
  </p>
  <p class='likeavoid avoid3'>3
  </p>
  <p class='likeavoid avoid4'>4
  </p>
  <p class='likeavoid avoid5'>5
  </p>
  <p class='likeavoid avoid6'>6
  </p>
  <p class='likeavoid avoid7'>7
  </p>
  <p class='likeavoid avoid8'>8
  </p>
  <p class='likeavoid avoid9'>9
  </p>
  <p class='likeavoid avoid10'>10
  </p>
  <p class='likeavoid avoid11'>11
  </p>
  <br>
</div>
<p class='white text-center' id='down1'> Scroll Down - Hover Here</p>

Upvotes: 2

Manjiri K
Manjiri K

Reputation: 126

In the setInterval(function, time) you can decide time based on how smoothly you want to scroll. Here I have used 100. If you are not using hover variable anywhere else in your code then you can remove it. coz it is not playing any role in scrolling down.

var hover = false;
var scrollInterval = null;

$("#down1").on({
mouseenter: function () {

    hover = true;

    scrollInterval = setInterval(function (){
        var y = $('#avoidOptions').scrollTop();  //your current y position on the page
        $('#avoidOptions').scrollTop(y + 150)
    }, 100);


},
mouseleave: function () {
    hover = false;
    clearInterval(scrollInterval)
    }
});

Upvotes: 1

Related Questions