0

$('.lorem').click(function() {
  $('.active').removeClass('active');
  $(this).addClass('active');
});

$(document).keydown(function(e){
    e.preventDefault();
  var i = $('.active').index('.lorem') + 1;
  var next = $('.lorem').eq(i);
  $('.active').removeClass('active');
  next.addClass('active');
});
.lorem{
line-height:21px;
cursor:pointer;
}

.active{
background:gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>

I have the above code to select next class lorem by pressing down arrow key.

And the similar code to select previous lorem by pressing up arrow key.

Imagine there are a lot more lorem divs on the page (about 200).

Is there a way to scroll page automatically when the selected div is outside of viewport, so it would be inside the viewport?

Daria Pydorenko
  • 1,754
  • 2
  • 18
  • 45
  • 1
    Possible duplicate of [How to tell if a DOM element is visible in the current viewport?](https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport) – gazdagergo Aug 13 '18 at 13:47

1 Answers1

0

You can add this code to your key down listener:

$('html, body').animate({
     scrollTop: next.offset().top
}, 1000);

And check if an element in viewport or not:

function isElementInViewport(el) {
     var rect = el.getBoundingClientRect();
     return (
           rect.top >= 0 &&
           rect.left >= 0 &&
           rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
           rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
     );
}

It will scroll the page down to the next element.

function isElementInViewport(el) {
 var rect = el.getBoundingClientRect();
 return (
   rect.top >= 0 &&
   rect.left >= 0 &&
   rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
   rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
   );
}

$('.lorem').click(function() {
  $('.active').removeClass('active');
  $(this).addClass('active');
});

$(document).keydown(function(e){
    e.preventDefault();
 var i = $('.active').index('.lorem') + 1;
 var next = $('.lorem').eq(i);
 $('.active').removeClass('active');
 next.addClass('active');

    if (next[0] && !isElementInViewport(next[0])) {
        $('html, body').animate({
            scrollTop: next.offset().top
        }, 1000);
    } 
});
.lorem{
line-height:21px;
cursor:pointer;
}

.active{
background:gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
<div class='lorem'>lorem</div>
Daria Pydorenko
  • 1,754
  • 2
  • 18
  • 45
  • hmm... it works, but... there is no need to scroll if element is already visible. –  Aug 13 '18 at 13:56