Yung Silva
Yung Silva

Reputation: 1500

Control horizontal scroll with javascript

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

Upvotes: 2

Views: 14963

Answers (1)

Ali Sheikhpour
Ali Sheikhpour

Reputation: 11045

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>

Upvotes: 2

Related Questions