Search code examples
javascripthtmlcssflexboxtailwind-css

Expandable sidenav using a draggable cursor


I'm trying to build a resizable sidenav. I have three sections and using flexbox and percentage width to define the initial size. I'm unable to get the resize functionality to work.

Codepen

In the javascript code I'm resetting the width of the sidenav to a the pixel amount. Does that override the percentage width? What is the best way to set initial width but have ability to resize?

var resizer = document.querySelector(".resizer"),
        sidebar = document.querySelector(".sidebar");

      function initResizerFn(resizer, sidebar) {
        // track current mouse position in x var
        var x, w;

        function rs_mousedownHandler(e) {
          x = e.clientX;

          var sbWidth = window.getComputedStyle(sidebar).width;
          w = parseInt(sbWidth, 10);

          document.addEventListener("mousemove", rs_mousemoveHandler);
          document.addEventListener("mouseup", rs_mouseupHandler);
        }

        function rs_mousemoveHandler(e) {
          var dx = e.clientX - x;

          var cw = w + dx; // complete width

          if (cw < 700) {
            sidebar.style.width = `${cw}px`;
          }
        }

        function rs_mouseupHandler() {
          // remove event mousemove && mouseup
          document.removeEventListener("mouseup", rs_mouseupHandler);
          document.removeEventListener("mousemove", rs_mousemoveHandler);
        }

        resizer.addEventListener("mousedown", rs_mousedownHandler);
      }

      initResizerFn(resizer, sidebar);
<!DOCTYPE html>
<html lang="en" class="h-full">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.tailwindcss.com"></script>
  </head>
  <body class="h-full">
    <div class="bg-gray-300 h-full flex">
      <div id="sidebar" class="bg-red-300 w-1/5 relative">1
        <div id="resizer" class="w-3 top-0 right-0 cursor-col-resize absolute bg-gray-600 h-full"></div>
      </div>
      <div class="bg-green-300 w-3/5">2</div>
      <div class="bg-blue-600 w-1/5">3</div>
    </div>
  </body>
</html>


Solution

  • You are using the wrong selector: you are using an ID in the HTML but, in your JavaScript query selector, you are using the class selector.

    Change to this and it will work:

    var resizer = document.querySelector("#resizer"), var sidebar = document.querySelector("#sidebar");