Control horizontal scroll with javascript

12,449

You have to do some calculation on the width of scrollbar and the width of scrolling content. Then decide how much is the percentage of the left position of scrollbar and pass it to the scroll percentage of content. I made all calcuations on window load to make sure that the size of elements are final:

$(window).on("load",function(){
    var scrollbarWidth=$(".scrollbar").width();
    var handleWidth=$(".handle").width();
    var remaining=scrollbarWidth-handleWidth;
    var hsWidth=$("ul.hs")[0].scrollWidth- $("ul.hs")[0].clientWidth; 
    var percent;

    $('.handle').draggable({
        axis: 'x',
        containment: 'parent',
        drag: function (event, ui) {
        percent=(ui.position.left/remaining);
        $("ul.hs").scrollLeft(percent*hsWidth);
   }
});

})
.page {
overflow: hidden;
}
.container {
width: 60%;
margin: auto;
}

h3 {
background: #dbd0bc;
color: #000;
padding: 1rem;
}

.hs {
list-style: none;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
width: 100%;
padding: 0 20% 2rem 20%;
}

.hs .item {
display: inline-block;
width: 17rem;
background: #dbd0bc;
text-align: center;
margin-right: 0.75rem;
height: 10rem;
white-space: normal;
}

.scrollbar {
width: 100%;
background: #bcc9d4;
height: 0.2rem;
position: relative;
margin: 3rem 0 3rem 0;
border-radius: 2rem;
height: 0.2rem;
}
.handle {
position: absolute;
width: 30%;
height: 0.7rem;
background: purple;
cursor: pointer;
cursor: -webkit-grab;
top: 50%;
transform: translateY(-50%);
border-radius: 2rem;
top: 1px !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
  integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
  crossorigin="anonymous"></script>
<div class="page">
    <div class="container">
    <h3>Container</h3>
    </div>

    <ul class="hs">
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    <li class="item">test</li>
    </ul>

    <div class="container">
    <div class="row">
        <div class="scrollbar">
        <div class="handle"></div>
        </div>
    </div>
    </div>
</div>

Share:
12,449

Related videos on Youtube

Yung Silva
Author by

Yung Silva

Updated on June 04, 2022

Comments

  • Yung Silva
    Yung Silva almost 2 years

    I'm working on a project and I'm stranded and i decided to ask you for help

    I have 2 Divs

    1- Div that stores content with full width

    2- Div that simulates a scrollbar, which will make scrolling of the first Div

    below my project image https://prnt.sc/n1vyg5

    100% functional example https://www.udacity.com/course/blockchain-developer-nanodegree--nd1309 in the session "Learn with the best"

    The structure is similar to this

    .page {
      overflow: hidden;
    }
    .container {
      width: 60%;
      margin: auto;
    }
    
    h3 {
      background: #dbd0bc;
      color: #000;
      padding: 1rem;
    }
    
    .hs {
      list-style: none;
      overflow-x: auto;
      overflow-y: hidden;
      white-space: nowrap;
      width: 100%;
      padding: 0 20% 2rem 20%;
    }
    
    .hs .item {
      display: inline-block;
      width: 17rem;
      background: #dbd0bc;
      text-align: center;
      margin-right: 0.75rem;
      height: 10rem;
      white-space: normal;
    }
    
    .scrollbar {
      width: 100%;
      background: #bcc9d4;
      height: 0.2rem;
      position: relative;
      margin: 3rem 0 3rem 0;
      border-radius: 2rem;
      height: 0.2rem;
    }
    .handle {
      position: absolute;
      width: 30%;
      height: 0.7rem;
      background: purple;
      cursor: pointer;
      cursor: -webkit-grab;
      top: 50%;
      transform: translateY(-50%);
      border-radius: 2rem;
      top: 1px !important;
    }
    
    <div class="page">
        <div class="container">
        <h3>Container</h3>
        </div>
    
        <ul class="hs">
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        <li class="item">test</li>
        </ul>
    
        <div class="container">
        <div class="row">
            <div class="scrollbar">
            <div class="handle"></div>
            </div>
        </div>
        </div>
    </div>
    
    $('.handle').draggable({
        axis: 'x',
        containment: 'parent',
        drag: function (event, ui) {
        console.log(ui.position.left)
        }
    });
    

    I do not know how to synchronize the drag of the '.handle' with the scrolling of the first div

  • Yung Silva
    Yung Silva about 5 years
    Perfect, it works, only remaining left the double way, when scrolling the content in a native way, fiddle with the div that simulates the scrollbar
  • Yung Silva
    Yung Silva about 5 years
    in fact there is some error in your calculations, I just do not know what ... content is coming to an end before '.handle' reaches the end
  • Ali Sheikhpour
    Ali Sheikhpour about 5 years
    OK! I had to omit the clientWidth from total width of hs and did it! @YungSilva