Adjust the size of three panels (left, middle, right) using Javascript, ensuring that the middle panel remains unchanged in size

I am a newcomer to JavaScript and currently working with HTML, CSS, and JS files. I have three panels - left, center, and right - that I want to resize. The left panel resizes correctly when dragging the column border.

https://i.stack.imgur.com/LxhUX.png

Now, I also want to be able to resize the central column by dragging the right side edge of the central column (as shown in red circle). This action should automatically adjust both the center and right columns.

My goal is to have the left panel and central panel move together when resizing the left panel, while keeping the right panel stationary. Similarly, when resizing the right panel, only the right panel and the central panel should adjust.

I suspect there might be an issue in my code:

   let prevX = e.x;
   const leftPanel = leftPane.getBoundingClientRect();

   let prevX2 = e.x;
   const centerPanel = centerPane.getBoundingClientRect();
  
   function mousemove(e) {
     let newX = prevX - e.x;
     leftPane.style.width = leftPanel.width - newX + "px";

     let newX2 = prevX2 - e.x;
     centerPane.style.width = centerPanel.width - newX2 + "px";
   }

Here is the complete code:

index.html

<div class="wrapper">
  <div class="pane left">
    This is the left pane.
  </div>
  
    <div class="pane center">
    This is the center pane.
    <div class="gutter"></div>
  </div>
  
  
  <div class="pane right">
    This is the right pane.
    <div class="gutter"></div>
  </div>
</div>

style.css

*, *::before, *::after {
 box-sizing: border-box;
}
  
 body {
  margin: 0;
}

.wrapper {
  height: 100vh;
  width: 100vw;
  background: #333;
  border: 6px solid #666;
  display: flex;
}

.pane {
  padding: 1em;
  color: #fff;
  min-width: 200px;
}

.left {
  
}

.center {
  position: relative;
}

.right {
  position: relative;
}

.gutter {
  width: 10px;
  height: 100%;
  background: #666;
  position: absolute;
  top: 0;
  left: 0;
  cursor: col-resize;
}

panel.js

const leftPane = document.querySelector(".left");
const centerPane = document.querySelector(".center");
const centerPane = document.querySelector(".right");
const gutter = document.querySelector(".gutter");


function resizer(e) {
  
  window.addEventListener('mousemove', mousemove);
  window.addEventListener('mouseup', mouseup);
  
  let prevX = e.x;
  const leftPanel = leftPane.getBoundingClientRect();
  
  function mousemove(e) {
    let newX = prevX - e.x;
    leftPane.style.width = leftPanel.width - newX + "px";
  }
  
  function mouseup() {
    window.removeEventListener('mousemove', mousemove);
    window.removeEventListener('mouseup', mouseup);
    
  }
  
  
}
gutter.addEventListener('mousedown', resizer);

Any assistance would be greatly appreciated!

Answer №1

  1. To implement event listeners on both .gutter elements, use querySelectorAll and gutter.forEach....

  2. You can target the previous panel based on the gutter being moved.

const gutters = document.querySelectorAll(".gutter");
const panes = document.querySelectorAll(".pane");
const minWidth = 200;

function resizer(e) {
  window.addEventListener("mousemove", mousemove);
  window.addEventListener("mouseup", mouseup);

  let prevX = e.x;
  const currentPane = e.currentTarget.parentNode;
  const currentPanel = currentPane.getBoundingClientRect();
  const prevPane = currentPane.previousElementSibling;
  const prevPanel = prevPane.getBoundingClientRect();

  function mousemove(e) {
    let newX = prevX - e.x;
    let newCurrentWidth = currentPanel.width + newX;
    let newPrevWidth = prevPanel.width - newX;
    if (newCurrentWidth < minWidth || newPrevWidth < minWidth) return;
    currentPane.style.width = newCurrentWidth + "px";
    prevPane.style.width = newPrevWidth + "px";
  }

  function mouseup() {
    window.removeEventListener("mousemove", mousemove);
    window.removeEventListener("mouseup", mouseup);
  }
}
gutters.forEach((gutter) => gutter.addEventListener("mousedown", resizer));
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.wrapper {
  height: 100vh;
  width: 100vw;
  background: #333;
  border: 6px solid #666;
  display: flex;
}

.pane {
  padding: 1em;
  color: #fff;
  min-width: 200px;
}

.center {
  position: relative;
}

.right {
  position: relative;
  flex-grow: 1;
}

.gutter {
  width: 10px;
  height: 100%;
  background: #666;
  position: absolute;
  top: 0;
  left: 0;
  cursor: col-resize;
}
<div class="wrapper">
  <div class="pane left">
    This is the left pane.
  </div>

  <div class="pane center">
    This is the center pane.
    <div class="gutter"></div>
  </div>


  <div class="pane right">
    This is the right pane.
    <div class="gutter"></div>
  </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using CSS, you can utilize a three-dot pattern to create a unique X

Hey there! I've got a menu with three dots that animate, and when I click on them, I want them to transform into an X shape. You can check out the demo here: demo Here's the HTML: <div class="dots"> <div class="dot"></div> & ...

Why is it that vanilla HTML/JS (including React) opts for camelCase in its styling conventions, while CSS does not follow the same pattern

Each type of technology for styling has its own set of conventions when it comes to naming properties, with camelCase and hyphenated-style being the two main options. When applying styles directly to an HTML DOM Node using JavaScript, the syntax would be ...

Updates to object properties are not appearing in Vue component

I am facing an issue with a Vue component that has a single prop, which is an object. Despite changing a property in this object, it does not reflect the update in the Vue template. Below is a simplified version of the component: <template> <p ...

Is there a way to directly update the value of a nested object array using v-model in VUE?

Looking to update a value in JSON using v-model { class: "data.child", "myform.input1": [true, "<input1 value>"] } <input type="text" v-model="<what should be inserted here?>" > //update the value directly in my ...

Switch Focus and Collapse Submenus upon Menu Click in Recursive React Menu

I've created a dynamic menu system in React using Material-UI that supports recursion for submenus. I'm aiming to implement the following features: 1. When a menu item is clicked, all other open submenus should close and focus on the clicked men ...

Versatile dataTable designed to seamlessly integrate with various data structures

My task is to develop an ajax dataTable that can handle a variety of data sources with different column names and data types. The challenge lies in the fact that I cannot predefine the column names or data types when coding the dataTable, as each data sour ...

Make sure PTable maintains a horizontal layout on any device with PrimeNG

When I view my Ptable on desktop or iPad, it looks like this: https://i.stack.imgur.com/ONqZV.png However, when I switch to a device like an iPhone X, it changes to this layout: https://i.stack.imgur.com/H2q7j.png I want the horizontal layout to displa ...

Trouble with $http response not appearing in AngularJS application

Currently, I am in the process of developing an angularjs application and encountering a challenging issue with setting up the $http connection to a php file. The header is displaying a response that I echoed from php. Nevertheless, two key problems persis ...

The initial setting of [opened]="true" causes an issue with the Angular Material date range picker

Recently, we completed the upgrade of our app from Angular 14 to 15.2.9, which includes Angular Material. The migration process went smoothly, and now our app is compiling and running without any errors. However, we encountered an issue with the mat-date-r ...

Angular and Node.js Integration: Compiling Files into a Single File

I have a question, is it possible to include multiple require js files in one file? If so, how can I create objects from them? Calling 'new AllPages.OnePage()' doesn't seem to work. To provide some context, I'm looking for something sim ...

Sharing information between External JavaScript and React JS/Redux

Incorporating React-redux into an externalJs application (built on a custom JS framework) has posed a challenge for me. I am trying to initialize data for the Redux store from externalJS, but it seems that the external script is unable to access the React ...

The input-group-btn is positioned to the right of the field, appearing to float

The input-group-btn for the targetDate field remains fixed on the right side of the input group despite screen width variations until I introduce the automatically generated CSS from the hottowel generator. I require assistance in identifying which aspect ...

Implementing CSS and JS for targeted elements or functions in WordPress

I am currently managing a WordPress WooCommerce website My goal is to implement bootstrap CSS and js specifically for a function on my WooCommerce checkout page. The code I have written is as follows: if( current_user_can('administrator')) { fu ...

Implementing dynamic AngularJS functionality within an older HTML structure using JQuery

I am facing an issue while trying to load dynamic content using AngularJS. In my system, I have legacy pages that utilize JQuery for dynamic loading. However, as I am developing new features with AngularJS, I am encountering the same problem with dynamic ...

A Vue element that has multiple exact click handlers will consistently trigger the click.exact method when clicked with system modifiers

According to the information found at https://v2.vuejs.org/v2/guide/events.html#exact-Modifier, I am attempting to build an element that triggers different methods based on additional keys pressed at the time of clicking. <span @click.exact="method ...

The .find() function conveniently jumps over the table directly following its parent element

After clicking on Inner Add Row, the correct row is added from the .charts-series table. However, when I click on Outer Add Row, a row from the .charts-series table is added instead of one from the .charts table. Here is the link to the example: http://jsf ...

Error: Scheme is not a valid function call

Currently, I am attempting to implement user registration functionality in a Node.js application using MongoDB. However, I encountered this error: var UtenteSchema = Scheme({ TypeError: Scheme is not a function Below is my model utente.js: cons ...

Determine the worth of various object attributes and delete them from the list

Currently, my dataset is structured like this: { roof: 'black', door: 'white', windows: 8 }, { roof: 'red', door: 'green', windows: 2 }, { roof: 'black', door: 'green', windows: ...

Is there a way to efficiently modify the positions of numerous markers on Google Maps while utilizing PhoneGap?

Hey there, I'm new to this and I have a service for tracking multiple cars. I'm using a timer to receive their locations, but I'm having trouble figuring out how to update the old marker with the new value. I've tried deleting all the m ...

Edit the settings for the dual-axis line chart's parameters

After countless hours of scouring the Internet and numerous attempts, I have come to the decision to seek help by posting my issue on this forum. I must confess, I am not the best developer. My approach usually involves finding pre-existing code that I ca ...