Challenges arising from updating the size and position of a div element during a mouse move event

As I work on creating a basic horizontal split pane using HTML, CSS, and JavaScript, I have drawn inspiration from this post.

While the vertical split pane functions smoothly, the horizontal version seems to be glitchy. The sizes and positions of the div elements seem to jump to unexpected values, and I'm struggling to identify the root cause.

The problem is somewhat subtle in the snippet below, but there is noticeable jitteriness and delays.

Snippet included below:

function dragElement(element, direction) {

    var md;
    const first = document.getElementById("map");
    const second = document.getElementById("table");

    element.onmousedown = onMouseDown;

    function onMouseDown(e) {
        md = {
            e,
            offsetLeft: element.offsetLeft,
            offsetTop: element.offsetTop,
            offsetBottom: element.offsetBottom,
            firstWidth: first.offsetWidth,
            secondWidth: second.offsetWidth,
            firstHeight: first.offsetHeight,
            secondHeight: first.offsetHeight
        };

        document.onmousemove = onMouseMove;

        document.onmouseup = () => {
            document.onmousemove = document.onmouseup = null;
        }
    }

    function onMouseMove(e) {

        var delta = {
            x: e.clientX - md.e.x,
            y: e.clientY - md.e.y
        };

        if (direction === "H") {
            delta.x = Math.min(Math.max(delta.x, - md.firstWidth),
                md.secondWidth);
            element.style.left = md.offsetLeft + delta.x + "px";
            first.style.width = (md.firstWidth + delta.x) + "px";
            second.style.width = (md.secondWidth - delta.x) + "px";
        }

        if (direction === "V") {
            delta.y = Math.min(Math.max(delta.y, - md.firstHeight), md.secondHeight);
            element.style.top = md.offsetTop + delta.y + "px";
            first.style.height = (md.firstHeight + delta.y) + "px";
            second.style.height = (md.secondHeight - delta.y) + "px";
        }
    }
}
dragElement(document.getElementById("separator"), "V");
html,
body {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}

.splitter {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}


/*for horizontal*/

#separator {
  cursor: row-resize;
  background-color: #aaa;
  background-repeat: no-repeat;
  background-position: center;
  width: 100%;
  height: 10px;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#map {
  width: 100%;
  height: 20%;
  min-height: 10px;
  padding: 0;
  margin: 0;
}

#table {
  width: 100%;
  height: 20%;
  min-height: 10px;
}
<div class="splitter">
  <div id="map"></div>
  <div id="separator"></div>
  <div id="table"></div>
</div>

Answer â„–1

One of the main reasons for the issue is that the secondHeight variable is becoming 0 when moving the element up and down. To address this, I calculate the height of the splitter class and subtract the height of the first element to get the correct value for the secondHeight variable.

secondHeight: (splitter.offsetHeight - first.offsetHeight)

function dragElement(element, direction) {

    var md;
    const first = document.getElementById("pic");
    const second = document.getElementById("description");
    const splitter = document.getElementById("container");

    element.onmousedown = onMouseDown;

    function onMouseDown(e) {
        md = {
            e,
            offsetLeft: element.offsetLeft,
            offsetTop: element.offsetTop,
            offsetBottom: element.offsetBottom,
            firstWidth: first.offsetWidth,
            secondWidth: second.offsetWidth,
            firstHeight: first.offsetHeight,
            secondHeight: (splitter.offsetHeight - first.offsetHeight)
        };
        document.onmousemove = onMouseMove;

        document.onmouseup = () => {
            document.onmousemove = document.onmouseup = null;
        }
    }

    function onMouseMove(e) {

        var delta = {
            x: e.clientX - md.e.x,
            y: e.clientY - md.e.y
        };

        if (direction === "H") {
            delta.x = Math.min(Math.max(delta.x, -md.firstWidth),
                md.secondWidth);
            element.style.left = md.offsetLeft + delta.x + "px";
            first.style.width = (md.firstWidth + delta.x) + "px";
            second.style.width = (md.secondWidth - delta.x) + "px";
        }

        if (direction === "V") {
            delta.y = Math.min(Math.max(delta.y, -md.firstHeight), md.secondHeight);
            element.style.top = md.offsetTop + delta.y + "px";
            first.style.height = (md.firstHeight + delta.y) + "px";
            second.style.height = (md.secondHeight - delta.y) + "px";
        }
    }
}

dragElement(document.getElementById("separator"), "V");
html,
body {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
}

.splitter {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}


/*for horizontal*/

#separator {
    cursor: row-resize;
    background-color: #aaa;
    background-repeat: no-repeat;
    background-position: center;
    width: 100%;
    height: 10px;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

#map {
    width: 100%;
    height: 20%;
    min-height: 10px;
    padding: 0;
    margin: 0;
}

#table {
    width: 100%;
    height: 20%;
    min-height: 10px;
}
<div id="container" class="splitter">
    <div id="map"></div>
    <div id="separator"></div>
    <div id="table"></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

Ways to customize the appearance of a react-chartist component

I recently created a React JS component that utilizes the amazing react ChartistGraph component. However, I've run into an issue where the default CSS of ChartistGraph seems to be conflicting with my custom styling. While there is plenty of documentat ...

Simplify a JSON array in JavaScript by removing nested layers

Looking to flatten a JSON nested array object into a flat array The key and value pair should be dynamic based on user input array I attempted to write the code myself but I'm not very familiar with JavaScript functions like concat, push, or others. ...

AngularJS directive not registering event after model update

Within my angularjs application, I have implemented an element directive that is equipped with an event listener. This listener is designed to respond to a broadcast event from the controller. app.directive('listItem', function(){ return { ...

Attempting to trigger CSS transitions using JavaScript will not be successful

I'm facing an issue where CSS transitions do not work as expected when triggered by JavaScript. let isSearchBarOpen = false; function toggleSearchBar() { if (isSearchBarOpen) { searchBar.style.display = "none"; } else { searchBar.sty ...

Developing an HTML table dynamically with JavaScript and incorporating CRM data

I am currently working on my JavaScript file, attempting to create an HTML table. Within this entity's record list are fields such as contractid, name, and address. var filter = "?$select=*&$filter=_plus_franchisee_value eq " + serviceProviderID ...

ng-options do not refresh automatically when modifying elements in the array

Having trouble updating the data in a select list? It seems that when selecting 'test', the value retrieved from the API is 'ÅšlÄ…sk' even though it's not listed. For example: I select 'test' but it shows as 'ÅšlÄ ...

Using HTML5 date input on an android browser

As I develop a web page catering to Android users, I have incorporated a date form control for users to input dates. However, I have noticed that on most devices, the native date selector does not pop up. Interestingly, on certain Samsung devices like the ...

Most effective method for integrating ajax URLs and browser history in a unique Joomla component

I have been given the task of enhancing the search functionality of a custom Joomla component that is solely operated through AJAX. Currently, the search does not handle URL/query strings, preventing users from using the browser back button to return to pr ...

Creating dynamic ng-model for input type [text] in AngularJS

Here is the current situation I'm dealing with in my code: <form name="task_form" ng-app="myApp" ng-submit="tasksubmit()"> <ul class="items-list"> <li ng-repeat="task in taskslist ...

Javascript auto submission fails to execute following the completion of the printer script

As someone new to javascript, I have a question. I have a function called sendToQuickPrinter() that prints correctly, but after it finishes executing, I need to automatically submit a form to return to my "cart.php" page. I feel like I'm almost there, ...

How can I transform an HTML element into a textarea using CSS or JavaScript?

While browsing a webpage, I discovered a <div> element with the class .plainMail and I want to find a way to easily select all its text by simply pressing Ctrl+A. Currently using Firefox 22, I am considering converting the div.plainMail into a texta ...

Error: The function $.simpleTicker is not defined

Every time I try to call a jQuery function, an error shows up: Uncaught TypeError: $.simpleTicker is not a function I attempted changing $ to jQuery but it didn't resolve the issue. This represents my jQuery code: (function ($) { 'use ...

Ensure that the image within the child div occupies the entire height of the parent div

I'm having a bit of trouble figuring this out and could use some input: There's a parent div with an unspecified height, determined by its content. Inside this parent div are two 'child' elements; however, I want only one to dictate t ...

VueJS - repeating input fields for file uploads

I need help removing duplicate items from an array in JavaScript, but when I try to delete one, it always deletes the last occurrence! https://i.sstatic.net/NeJRJ.jpg let app = new Vue({ el: '#app', data: { items: [] }, methods: { ...

Executing a separate function after each iteration of an ajax call within a loop using Jquery

I am faced with a situation where an ajax function must be run inside a loop that depends on the array's size. How can I execute another function after the ajax call is completed and outside the loop? Is this achievable? Below is the function: funct ...

What are the potential causes of an asynchronous error in a WebGLRenderingContext?

While running an animation loop, I encountered a peculiar error message that reads... GL ERROR :GL_INVALID_OPERATION : glDrawElements: Source and destination textures of the draw are the same. This error seems to occur randomly after 2 or 3 animation fr ...

The placement of an element is determined by its size and proportions

I'm experiencing some issues with avatars on my website. When the avatar size is set to 35x35 pixels, everything works fine. However, problems arise when the dimensions exceed 35x35 pixels. I suspect that the problem is related to the "position: abso ...

Adjust the sizes of the points according to the level of zoom

I've been working on creating a dynamic map in d3.js that displays US Science funding agencies as points, with their sizes scaling based on zoom level. I referred to this starter kit for guidance. While there are other solutions out there, they often ...

Creating an iPad-inspired password field experience in a text input with jquery: A step-by-step guide

Looking for a plugin that mimics the iPad's password field behavior for credit card number entry. The focus should only reveal the entered digit and then switch to a bullet as the next digit is typed. Additionally, all previously entered digits should ...

Passing Props in Material-UI v5xx with ReactJS: A Beginner's Guide

Struggling with the fact that useStyle() isn't functioning properly in my material-UI v5xx version, I found myself at a loss on how to pass props in this updated edition. In Material-UI v4, it was as simple as: const Navbar = () => { const [open ...