1

I want to implement a custom scrollbar using javascript. I have following jsfiddle code

JSFIDDLE

<div class="container">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
  </ul>
</div>

CSS

.container {
  height: 100px;
  width: 100px;
  overflow-y: scroll;
}

It currently has browser's default scrollbar but I want to implement my own with pure javascript. I know there are css3 solutions available but it has browser compatibility issues. There are also plenty of jquery plugins available but my requirement is only javascript.

How can I implement this?

1
  • you know, quick clarification: when you say no plugins, do you mean no frameworks like jquery, or do you mean no pre-made plugins? Commented May 12, 2016 at 22:30

1 Answer 1

4

This is just an quick example. JSFIDDLE here. Please check.

TODO:

  1. Add listener to key event, like up arrow, down arrow and space
  2. Add listener to mouse scroll event.
  3. Drag and drop event on scroll anchor.
  4. Touch event (if touch devices needed to be supported).

Hope this is useful.

UPDATE

Remove jQuery. Got a mistake, didn't read the question very carefully.

var scrollBarContainer = document.getElementById('scroll');
var anchor = document.getElementById('anchor');
var container = document.getElementById('container');
var content = document.querySelectorAll('#container > *:not(#scroll)');

var containerHeight = container.offsetHeight;
var contentHeight = 0;
console.log(content);
for (var i = 0; i < content.length; i++) {
  contentHeight += content[i].scrollHeight;
}

anchor.style.height = Math.floor(containerHeight / contentHeight * containerHeight) + 'px';

var flag_mouseDown = false;
var oldMousePosition = 0;
var oldAnchorPosition = 0;
scrollBarContainer.addEventListener('mousedown', function(e) {
  if (e.target.nodeName === 'DIV') {
    var distance = e.clientY - container.offsetTop - anchor.offsetHeight / 2;
    if (distance < 0) {
      distance = 0;
    } else if (distance + anchor.offsetHeight > containerHeight) {
      distance = containerHeight - anchor.offsetHeight;
    }
    anchor.style.top = distance + 'px';
    moveContent();
  } else if (e.target.nodeName === 'SPAN') {
    flag_mouseDown = true;
    oldMousePosition = e.clientY;
    oldAnchorPosition = anchor.offsetTop;
  }
});
scrollBarContainer.addEventListener('mouseup', function(e) {
  flag_mouseDown = false;
  oldMousePosition = e.clientY;
  oldAnchorPosition = anchor.offsetTop;
});
scrollBarContainer.addEventListener('mousemove', function(e) {
  if (!flag_mouseDown) {
    return;
  }

  var distance = e.clientY - oldMousePosition;
  var newPosition = oldAnchorPosition + distance;

  if (newPosition < 0) {
    newPosition = 0;
  } else if (newPosition + anchor.offsetHeight > containerHeight) {
    newPosition = containerHeight - anchor.offsetHeight;
  }
  anchor.style.top = newPosition + 'px';
  moveContent();
});

var moveContent = function() {
  var postion = anchor.offsetTop / (containerHeight - anchor.offsetHeight);
  var newPosition = (0 - postion * (contentHeight - containerHeight)) + 'px';
  console.log(anchor.offsetTop, container.offsetTop, containerHeight, anchor.offsetHeight);
  console.log(postion, contentHeight, containerHeight);
  for (var i = 0; i < content.length; i++) {
    content[i].style.marginTop = newPosition;
  }
};
.container {
  height: 100px;
  width: 100px;
  overflow-y: hidden;
  position: relative;
  margin-right: 17px;
}
#scroll {
  position: absolute;
  top: 0;
  right: 0;
  width: 17px;
  height: 100%;
  border-left: 1px solid #3e3e3e;
  background-color: #eee;
}
#anchor {
  position: absolute;
  top: 0;
  right: 0;
  width: 17px;
  height: 10px;
  background-color: #aaa;
}
#anchor:hover,
#anchor:active {
  background-color: #333;
}
ul {
  margin: 0;
}
<div id="container" class="container">
  <div id="scroll">
    <span id="anchor"></span>
  </div>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
  </ul>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.