How to control Scroll in JS / jQuery

Asked

Viewed 743 times

3

I’m having a question, I created a system where there’s a 'navigation' between items, but I couldn’t make the scrollbar 'track' the items. Would anyone have an idea how to get him to follow?

Link Fiddle

$(document).ready(function(){
    let elements = $(".item-list");
    let total = elements.length;
    
   $(".item-list").on("click", function(e){
        changeItemByElement(this);
   });

   $("#btnMoveDown").on("click", moveDown => {
       let status = false;
       let i = 1;
       let element;
       
       while(!status){
            element = $(`#item_${i}`);
            element.scrollTop();

            status = element.hasClass("selected");
            
            if(status){
                i = i == total ? total - 1: i;  
                element = $(`#item_${i+1}`);
            }
            i++;
       }

       changeItemByElement(element);
   });

   $("#btnMoveUp").on("click", moveUp => {
        let status = false;
        let i = 1;
        let element;
        
        while(!status){
            element = $(`#item_${i}`);
            status = element.hasClass("selected");
            
            if(status){
                i = i == 1 ? i = 2 : i;
                element = $(`#item_${i-1}`);
            }
            i++;
        }

        changeItemByElement(element);
        $(".dropdown").scroll(scroll => {
            console.log('item');
        });
   });
  
   let changeItemByElement = function(element){
       $(".item-list").removeClass("selected");
       $(element).addClass("selected");
   }

         
});
.dropdown{
	height: 140px;
	overflow-y: hidden;
}

.menu-scroll {
  overflow-y: scroll;
  max-height: 200px;
}

.button-action{
	padding: 5%;
}

.item-list{
	padding: 2%;
}

.selected{
	background: #f0f0f0;
	font-weight: bolder;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">        
    <link rel="stylesheet" href="css/index.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/css/bootstrap-reboot.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/css/bootstrap.min.css" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</head>
<body>
    <div class="container">
        <div class="row">
            <div class='col-xl-10 col-sm-10 col-md-10 col-lg-10'>
                <div class="box">
                    <ul class="list-unstyled dropdown menu-scroll">
                        <li class="item-list selected" id="item_1"><span>Item 1</span></li>
                        <li class="item-list" id="item_2"><span>Item 2</span></li>
                        <li class="item-list" id="item_3"><span>Item 3</span></li>
                        <li class="item-list" id="item_4"><span>Item 4</span></li>
                        <li class="item-list" id="item_5"><span>Item 5</span></li>
                        <li class="item-list" id="item_6"><span>Item 6</span></li>
                        <li class="item-list" id="item_7"><span>Item 7</span></li>
                        <li class="item-list" id="item_8"><span>Item 8</span></li>
                        <li class="item-list" id="item_9"><span>Item 9</span></li>
                        <li class="item-list" id="item_10"><span>Item 10</span></li>
                    </ul>
                </div>
            </div>
            <div class="col-xl-2 col-sm-2 col-lg-2">
                <ul class="list list-unstyled">
                    <li class="button-action">
                        <button type="button" id="btnMoveUp" class="btn btn-default">
                            <i class="fa fa-arrow-up"></i>
                        </button>
                    </li>
                    <li class="button-action">
                        <button type="button" id="btnMoveDown" class="btn btn-default">
                            <i class="fa fa-arrow-down"></i>
                        </button>
                    </li>
                </ul>	
            </div>            
        </div>
    </div>
    <!-- JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/js/bootstrap.bundle.min.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

2 answers

3


For this you will have to analyze the scroll through the method $(element). scrollTop() of jQuery. Example:

$(document).ready(function(){
    let elements = $(".item-list");
    let total = elements.length;
    
   $(".item-list").on("click", function(e){
        changeItemByElement(this);
   });

   $("#btnMoveDown").on("click", moveDown => {
       let status = false;
       let i = 1;
       let element;
       
       while(!status){
            element = $(`#item_${i}`);
            element.scrollTop();

            status = element.hasClass("selected");
            
            if(status){
                i = i == total ? total - 1: i;  
                element = $(`#item_${i+1}`);
            }
            i++;
       }

       changeItemByElement(element);
   });

   $("#btnMoveUp").on("click", moveUp => {
        let status = false;
        let i = 1;
        let element;
        
        while(!status){
            element = $(`#item_${i}`);
            status = element.hasClass("selected");
            
            if(status){
                i = i == 1 ? i = 2 : i;
                element = $(`#item_${i-1}`);
            }
            i++;
        }

        changeItemByElement(element);
   });
  
   let changeItemByElement = function(element){
       $(".item-list").removeClass("selected");
       $(element).addClass("selected");
       checkScroll(element);
   }
   
   let checkScroll = function(element) {
      let scrollTop = $('.menu-scroll').scrollTop();

      $('.menu-scroll').scrollTop(0);
      let top = $(element).offset().top - $('.menu-scroll').offset().top;

      if(top + $(element).outerHeight() > $('.menu-scroll').outerHeight() + scrollTop)
          scrollTop = top - $('.menu-scroll').height() + $(element).outerHeight();
      else if(top < scrollTop)
        scrollTop = top;
      
      $('.menu-scroll').scrollTop(scrollTop);
   }

         
});
.dropdown{
	height: 140px;
	overflow-y: hidden;
}

.menu-scroll {
  overflow-y: scroll;
  max-height: 200px;
}

.button-action{
	padding: 5%;
}

.item-list{
	padding: 2%;
}

.selected{
	background: #f0f0f0;
	font-weight: bolder;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">        
    <link rel="stylesheet" href="css/index.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/css/bootstrap-reboot.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/css/bootstrap.min.css" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</head>
<body>
    <div class="container">
        <div class="row">
            <div class='col-xl-10 col-sm-10 col-md-10 col-lg-10'>
                <div class="box">
                    <ul class="list-unstyled dropdown menu-scroll">
                        <li class="item-list selected" id="item_1"><span>Item 1</span></li>
                        <li class="item-list" id="item_2"><span>Item 2</span></li>
                        <li class="item-list" id="item_3"><span>Item 3</span></li>
                        <li class="item-list" id="item_4"><span>Item 4</span></li>
                        <li class="item-list" id="item_5"><span>Item 5</span></li>
                        <li class="item-list" id="item_6"><span>Item 6</span></li>
                        <li class="item-list" id="item_7"><span>Item 7</span></li>
                        <li class="item-list" id="item_8"><span>Item 8</span></li>
                        <li class="item-list" id="item_9"><span>Item 9</span></li>
                        <li class="item-list" id="item_10"><span>Item 10</span></li>
                    </ul>
                </div>
            </div>
            <div class="col-xl-2 col-sm-2 col-lg-2">
                <ul class="list list-unstyled">
                    <li class="button-action">
                        <button type="button" id="btnMoveUp" class="btn btn-default">
                            <i class="fa fa-arrow-up"></i>
                        </button>
                    </li>
                    <li class="button-action">
                        <button type="button" id="btnMoveDown" class="btn btn-default">
                            <i class="fa fa-arrow-down"></i>
                        </button>
                    </li>
                </ul>	
            </div>            
        </div>
    </div>
    <!-- JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/js/bootstrap.bundle.min.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

  • This is exactly what I needed, thanks for the strength @Diegomarques!

  • Arrange :), gives an analysis in the method I made for you to absorb the logic, if you have doubts just warn.

2

You can use an animation to scroll the items. In the example below I used the method .animate that will scroll the selected item to the top of the menu:

$(document).ready(function(){
    let elements = $(".item-list");
    let total = elements.length;
    
   $(".item-list").on("click", function(e){
        changeItemByElement(this);
   });

   $("#btnMoveDown").on("click", moveDown => {
       let status = false;
       let i = 1;
       let element;
       
       while(!status){
            element = $(`#item_${i}`);
            element.scrollTop();

            status = element.hasClass("selected");
            
            if(status){
                i = i == total ? total - 1: i;  
                element = $(`#item_${i+1}`);
            }
            i++;
       }

       changeItemByElement(element);
   });

   $("#btnMoveUp").on("click", moveUp => {
        let status = false;
        let i = 1;
        let element;
        
        while(!status){
            element = $(`#item_${i}`);
            status = element.hasClass("selected");
            
            if(status){
                i = i == 1 ? i = 2 : i;
                element = $(`#item_${i-1}`);
            }
            i++;
        }

        changeItemByElement(element);
        $(".dropdown").scroll(scroll => {
           // console.log('item');
        });
   });
  
   let changeItemByElement = function(element){
       $(".item-list").removeClass("selected");
       $(element).addClass("selected");
       
       var menuDiv = $(".menu-scroll").offset().top; // distâcia do menu ao topo da página
       var distLi = $(element).offset().top; // distância dos itens ao topo
       var menuScr = $(".menu-scroll").scrollTop(); // rolagem do menu
       
       var mlDist = distLi-menuDiv; // diferença
       
       $(".menu-scroll").animate({
          scrollTop: Math.floor(mlDist-menuScr) > 1 ?
          mlDist-menuScr :
          mlDist+menuScr
       }, 300);
       
   }

         
});
.dropdown{
	height: 140px;
	overflow-y: hidden;
}

.menu-scroll {
  overflow-y: scroll;
  max-height: 200px;
}

.button-action{
	padding: 5%;
}

.item-list{
	padding: 2%;
}

.selected{
	background: #f0f0f0;
	font-weight: bolder;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />

<div class="container">
        <div class="row">
            <div class='col-xl-10 col-sm-10 col-md-10 col-lg-10'>
                <div class="box">
                    <ul class="list-unstyled dropdown menu-scroll">
                        <li class="item-list selected" id="item_1"><span>Item 1</span></li>
                        <li class="item-list" id="item_2"><span>Item 2</span></li>
                        <li class="item-list" id="item_3"><span>Item 3</span></li>
                        <li class="item-list" id="item_4"><span>Item 4</span></li>
                        <li class="item-list" id="item_5"><span>Item 5</span></li>
                        <li class="item-list" id="item_6"><span>Item 6</span></li>
                        <li class="item-list" id="item_7"><span>Item 7</span></li>
                        <li class="item-list" id="item_8"><span>Item 8</span></li>
                        <li class="item-list" id="item_9"><span>Item 9</span></li>
                        <li class="item-list" id="item_10"><span>Item 10</span></li>
                    </ul>
                </div>
            </div>
            <div class="col-xl-2 col-sm-2 col-lg-2">
                <ul class="list list-unstyled">
                    <li class="button-action">
                        <button type="button" id="btnMoveUp" class="btn btn-default">
                            <i class="fa fa-arrow-up"></i>
                        </button>
                    </li>
                    <li class="button-action">
                        <button type="button" id="btnMoveDown" class="btn btn-default">
                            <i class="fa fa-arrow-down"></i>
                        </button>
                    </li>
                </ul>	
            </div>            
        </div>
    </div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.