Reputation: 3512
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
Reputation: 34158
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.
<br />
just to add space so I removed it and added padding at the bottom to the parent instead<p></p>
consider a <div>
with margin or padding to space things$('.likeavoid').index();
or if you know the index value $('.likeavoid').eq(5);
to target onefunction 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
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
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
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