I was searching for a solution that required minimal CSS modifications. While there was a minor bug (FIXED), I believe this example will give you a good starting point. Feel free to check out the DEMO.
In addition, my goal was to utilize DOM Traversal methods like .next() and .prev() in order to reduce reliance on specific attributes and make it easily reusable if needed multiple times on a page.
Edit - More Details
The concept here is that upon clicking a .handle
, we calculate the total width (var tWidth) of the .prev()
and .next()
divs relative to the .handle
within the DOM. We then use the initial mouse position (var sPos) to determine how many pixels our mouse has moved (e.pageX). This calculation provides us with the correct width for the .prev( )
div during the mousemove
event. To obtain the width of the .next()
div, we subtract the width of the .prev()
div from the total width (var tWidth) stored upon clicking the .handle
. I hope this clarifies things! Let me know if you have any more questions, although I may not be available until tomorrow.
HTML
<div class="container">
<div id="left"></div>
<div id="l-handle" class="handle"></div>
<div id="middle"></div>
<div id="r-handle" class="handle"></div>
<div id="right"></div>
</div>
CSS
#left, #middle, #right {
display: inline-block;
background: #e5e5e5;
min-height: 200px;
margin: 0px;
}
#l-handle, #r-handle {
display: inline-block;
background: #000;
width: 2px;
min-height: 200px;
cursor: col-resize;
margin: 0px;
}
jQuery
var isDragging = false,
cWidth = $('.container').width(),
sPos,
handle,
tWidth;
$('#left, #middle, #right').width((cWidth / 3) - 7); // Set the initial width of content sections
$('.handle').on('mousedown', function(e){
isDragging = true;
sPos = e.pageX;
handle = $(this);
tWidth = handle.prev().width() + handle.next().width();
});
$(window).on('mouseup', function(e){
isDragging = false;
});
$('.container').on('mousemove', function(e){
if(isDragging){
var cPos = sPos - e.pageX;
handle.prev().width((tWidth / 2) - cPos);
handle.next().width(tWidth - handle.prev().width());
}
});
Edit
The bug stemmed from two issues:
1) During mousemove, we were dividing the total width by two instead of using an updated mouse offset.
2) The sPos value wasn't updating on mousemove, remaining static based on the initial click location.
Resolution
Updates include adjusting sPos on mousemove to accurately reflect the mouse's movement for precise calculations. By subtracting the .next() div's width from the total width, then further subtracting the current mouse position, we ensure accurate resizing. Check the updated fiddle.
$('.container').on('mousemove', function(e){
var cPos = sPos - e.pageX;
if(isDragging && ((tWidth - handle.next().width()) - cPos) <= tWidth){
handle.prev().width((tWidth - handle.next().width()) - cPos);
handle.next().width(tWidth - handle.prev().width());
sPos = e.pageX;
}
});
Edit
An additional condition was added on mousemove to prevent dragging beyond the total width (var tWidth).