daliaessam
daliaessam

Reputation: 1666

Jquery scroll to div if not visible and stop scrolling on user interaction

I use the jquery code below to let the page smoothly scroll to a specific div if it is not currently visible on the screen:

if (!$('#list-panel').visible(true)) {
    $('html, body').animate({ scrollTop: $('#article-panel').offset().top - 150}, 4000);
}

This works fine as need. What I want is if the user while scrolling hits any key on the keyboard or the mouse, it should stop the scroll so the user can interact normally. Currently, the user has to wait until the scrolling is totally done. Please note that by default, I need it to scroll slowly and smoothly as you see the code within 4 seconds, but if the user decided not to wait and hit the keyboard or the mouse then the scroll should stop immediately.

Upvotes: 0

Views: 967

Answers (2)

user5201742
user5201742

Reputation:

UPDATE

For handling multiple events, it's better to bind these events. For example, click starts animation and keypress stops it:

$('html, body').bind({
          'click' : function(){
            $('html, body').animate({ scrollTop: $('#d4').offset().top}, {duration:4000});
          },
          'keyup' : function(){
            $('html, body').stop();
          }

        }); 

For mobile, you can add tap, swipe, etc... using jQuery mobile (https://jquerymobile.com/)

Code pen https://codepen.io/anon/pen/RRworb

===

jQuery animate function has a step callback you could use to check user has clicked or pressed a key.

A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set.

Info: http://api.jquery.com/animate/

I've made an example here:

HTML

<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>

CSS

#d1, #d2, #d3, #d4 {
  height: 300px;
  width: 100%;
}

#d1{
  background-color: red;
}

#d2{
  background-color: blue;
}

#d3{
  background-color: black;
  display: none;
}

#d4{
  background-color: yellow;
}

JS

if ( $('#d3').css('display') == 'none' ) {

    $('html, body').animate({ scrollTop: $('#d4').offset().top}, {duration:4000,
                           step : function(){
        $('html, body').on('click',function(e){
          $('html, body').stop();
        });
    }});
}

CodePen https://codepen.io/anon/pen/zBYoOj

Upvotes: 2

Parag Bhayani
Parag Bhayani

Reputation: 3330

The best approach would be registering an event when you start the animation, and later on unregister the event, so with the time it doesn't have too many registered events on your element

to stop animation you could use below code

$('html, body').stop();

On any specific event it becomes

$('html, body').on('click'), function() {
    $('html, body').stop();
}

but now you want to do this when only animation starts, and you need to call that event handler only once so it should be

function stopScroll () {
        $('html, body').stop();
}

$('html, body').animate({ scrollTop: $('#article-panel').offset().top - 150}, {duration:5000}).one("click", stopScroll);

but also you want to deregister events after your code completes execution

function stopScroll () {
    $('html, body').stop();
}

$('html, body').animate({ scrollTop: $('#article-panel').offset().top - 150}, {duration:5000, complete:function(){
    $('html, body').un("click", stopScroll);
}}).one("click", stopScroll);

Upvotes: 1

Related Questions