This is a simple HTML placeholder for a thing I am working on.
You can ignore the rest (I hope!) and focus on this sole issue:
The zoom on the image works, and it focus on the quadrant you press on, as I want it to. But it only places top and bottom scroll bars if the zoom is made on the top left quadrant.
I want it to always show the scroll bars. What am I missing?
Thanks
var images = ["Species_copy_number.png", "Species_coverage.png", "Species_distribution.png", "Gene_copy_distribution.png"];
var descriptions = ["cariño", "muis bueno", "caliente", "CABRÓN!"];
var titles = ["ay", "ay ay", "ay ay ay", "AY AY AY MI HIJJJJJJOOOOOOOOOOOOO"];
function changeImage(index){
var img = document.getElementById("img_place");
img.src = "Figures/" + images[index];
document.getElementById("desc_place").textContent = descriptions[index];
document.getElementById("subtitle").textContent = titles[index];
}
window.zoomedIn = false;
window.onload = function(){
var canvas = document.getElementById("img_wrapper");
canvas.onclick = function(event){
var imgWrapper = this, zoomContainer = document.getElementById("zoom-container");
var imgPlace = document.getElementById("img_place");
if (window.zoomedIn) {
imgPlace.setAttribute("style", "transform :\"\"");
window.zoomedIn = false;
} else {
var width = zoomContainer.offsetTop + zoomContainer.offsetWidth;
var height = zoomContainer.offsetTop + zoomContainer.offsetHeight;
var tro = (zoomContainer.offsetTop + event.clientY > height / 2) ? "bottom" : "top";
tro += (zoomContainer.offsetLeft + event.clientX > width / 2) ? " right" : " left";
imgPlace.setAttribute("style", "transform-origin: "+ tro + " 0px; transform: scale(2);");
window.zoomedIn = true;
}
}
}
body, html { height: 100%; }
.flex-container {
display: -webkit-flex;
display: -ms-flex;
display: -moz-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.flex-item {
display: -webkit-flex;
display: -ms-flex;
display: -moz-flex;
display: flex;
margin: 3px;
padding: 0 0 10px;
}
.flex-item img{
width: 100%;
}
span {
min-width: 5em;
margin-top: 3em;
padding-right: 1em;
}
a {
padding-left: 0.3em;
}
.img-wrapper {
border: 1px solid gray;
}
img {
height: 100%;
width: 100%;
}
#zoom-container{
overflow: auto;
}
<h1>Mega title</h1>
<h2 id="subtitle">Title</h2>
<div class="flex-container">
<div class="flex-item">
<span>
cenas<br>
Img #1
Img #2
cenas<br>
Img #3
Img #4
</span>
<div id="zoom-container">
<div id="img_wrapper" class="img-wrapper">
<img id="img_place" src="https://i.ytimg.com/vi/ddqvuwXBK5k/maxresdefault.jpg"/>
</div>
</div>
</div>
</div>
<h2>Description</h2>
<span id="desc_place">Description</span>
The coordinate system starts from left upper corner of the parent element. Since you are transforming the origin of the image in your quadrant on click, you are starting it from a clipped point.
With regard to document flow directions, the top and left sides are the block-start and inline-start sides and browsers or UA behave as though content is clipped beyond that direction.
From W3C specs: Scrolling Origin, Direction, and Restriction
Due to Web-compatibility constraints ... UAs must clip the scrollable overflow region of scroll containers on the block-start and inline-start sides of the box (thereby behaving as if they had no scrollable overflow on that side).
There may be a JS hack. I am not sure.
Here are some work-arounds (with) better explanations.
CSS Transforms / JS to zoom into element
Canvas Method
The best I could think of in your case is to add this CSS for .img-wrapper
.img-wrapper {
height: 100%;
width: 100%;
overflow: auto
}
and add overflow: auto; to imgPlace.setAttribute()in your last else statement
imgPlace.setAttribute("style", "transform-origin: "+ tro + " 0px; transform: scale(2);position: relative;overflow: auto;");
That way you will get scroll bars in quadrant 1, 2 and 3. In the fourth quadrant scroll restriction will be enabled.
Here is a codepen edit of your code
Simply create two new classes in css
.zoomed {
transform:scale(2);
}
.scroll {
overflow:scroll;
}
Add some jquery code
$ ('#img_wrapper').click(function() {
var top = $('#img_place').height() / 2;
$('#img_place').toggleClass('zoomed');
$(this).toggleClass('scroll');
if ($('#img_place').hasClass('zoomed')) {
$('#img_place').css('top', top);
}
else {
$('#img_place').css('top', '0');
}
});
Here is Updated fiddle chek out this.
Hope it's fine for you
Related
Intentionally posting this question on stackoverflow instead of posting it on salesforce.stackexchange.com as this problem is specific to JS/CSS
I have below LWC playground where it is not working as expected
https://app.lwc.studio/edit/CTHEQCGrn18rKmQQ0zs1 (unfortunately you might have to login to webcomponents.dev to access this link)
but on the below code pen the same is working as expected not sure what am I doing wrong.
https://codepen.io/gs650x/pen/qByPQKP
I have below HTML
<section class="resizeable-container" >
<div class="resizeable-item">
DIV1
</div>
<div class="resizer-x" onmousedown={handleOnMouseDown} onmouseup={handleOnMouseUp}></div>
<div class="resizeable-item">
DIV2
</div>
</section>
CSS
.resizeable-container {
display: flex;
min-height: 80vh;
}
.resizeable-item {
flex: 50%;
overflow: auto;
}
.resizer-x {
position: relative;
display: flex;
justify-content: center;
align-items: center;
background: hsl(212, 100%, 17%);
padding: 4px;
}
.resizer-x {
z-index: 2;
cursor: col-resize;
}
.resizer-x::before,
.resizer-x::after {
content: "";
width: 2px;
height: 16px;
margin: 2px;
background: lightgray;
}
Below is the javascript
renderedCallback() {
if (!resizer)
resizer = this.template.querySelector(".resizer-x")
//In case mouse up event occurs outside the resizer element
document.addEventListener("mouseup", this.handleOnMouseUp)
}
handleOnMouseDown(event) {
event.preventDefault();
document.addEventListener("mousemove", this.handleOnMouseMove)
document.addEventListener("mouseup", this.handleOnMouseUp)
}
handleOnMouseMove(event) {
event.preventDefault();
const clientX = event.clientX;
const deltaX = clientX - (resizer._clientX || clientX);
resizer._clientX = clientX;
const { previousElementSibling, nextElementSibling } = resizer
// LEFT
if (deltaX < 0) {
const width = Math.round(parseInt(window.getComputedStyle(previousElementSibling).width) + deltaX)
previousElementSibling.style.flex = `0 ${clientX < 10 ? 0 : clientX}px`
nextElementSibling.style.flex = "1 0"
}
// RIGHT
if (deltaX > 0) {
const width = Math.round(parseInt(window.getComputedStyle(nextElementSibling).width) - deltaX)
nextElementSibling.style.flex = `0 ${width < 10 ? 0 : width}px`
previousElementSibling.style.flex = "1 0"
}
}
handleOnMouseUp(event) {
event.preventDefault();
document.removeEventListener("mousemove", this.handleOnMouseMove)
document.removeEventListener("mouseup", this.handleOnMouseUp)
delete event._clientX
}
This works well on my 32 inches monitor but it is not working on my 14 inch laptop
expectation is to move the cursor and resizer-x at the same time but resizer-x moves first and then the cursor moves and mouse up only works if it is coming from the resizer-x anywhere else it is not working. I have added eventListener to document not on a particular object but still removeEventListener to stop handleMouseMove function doesn't stop.
Below is the code pen where it is working as expected but in LWC it doesn't behave in the same manner
https://codepen.io/gs650x/pen/qByPQKP
I'm given to understand that the <frameset> tag is deprecated as of HTML5. Thankfully, Chrome still supports rendering it, and unfortunately, it's currently the only thing I've found that fits my use case.
The important element of the <frameset> tag that other frame-like objects lack is draggable borders, which I haven't been able to get working with iframes even with a prohibitive amount of javascript assistance.
The other important thing in my case is that one of the frames contains a button/link that causes the other frame to disappear or reappear. When that happens, the frames should resize appropriately to fill the space.
My current HTML looks like the following MCVE:
index.html
<html>
<head>
<script language="javascript">
function toggleBottomFrame() {
var bottomFrame = document.getElementById("bottomFrame");
var horizFrameset = document.getElementById("horizFrameset");
if (bottomFrame.style.display == "none") {
bottomFrame.style.display = "";
horizFrameset.rows = "*,25%";
} else {
bottomFrame.style.display = "none";
horizFrameset.rows = "*,0px";
}
}
document.toggleBottomFrame = toggleBottomFrame;
</script>
</head>
<frameset id="horizFrameset" rows="*,0px">
<frameset id="vertFrameset" cols="300px,*">
<frame id="topLeftFrame" src="buttonpage.html"></frame>
<frame id="topRightFrame"></frame>
</frameset>
<frame id="bottomFrame" style="display:none"></frame>
</frameset>
</html>
buttonpage.html
<html>
<head></head>
<body>
<button onclick="parent.frameElement.ownerDocument.toggleBottomFrame();">
</body>
</html>
This works both in the IE11 that the code was initially written for (and needs to continue to support), as well as in Chrome.
How do I implement the exact same functionality (including, most importantly, the ability to drag around the borders of the frames with my mouse to expand or shrink one of the frames) using non-deprecated functionality?
If possible, I'd like a solution in standard client-side JS or HTML, without needing to import another library like resize.js. This is meant for a very lightweight frontend, and I don't want to bloat it down with libraries I don't need.
You should be able to achieve the shrink and grown functionality using the flex layout. Below 2 approaches may work. Both the approaches has the right section and bottom section as iframe and the left section has button to show and hide the right and bottom sections.
Option 1
Using flex and using the css resize property.
Drawback is that you will need to resize using the resize button shown at the bottom right corners. The left section's bottom right corner can be used for horizontal resizing and the right section's bottom right corner can be used for vertical resizing. Note that due to the iframe contents the right section's bottom right corner resize button may not be visible, but if you bring the cursor to the bottom right you will see the cursor changing to resize and allowing you to resize.
function toggleBottom() {
if (document.getElementById('bottomFrame').clientHeight > 0) {
document.getElementById('topFrame').style.height = '100%';
} else {
document.getElementById('topFrame').style.height = '80%';
}
}
function toggleRight() {
if (document.getElementById('topRightFrame').clientWidth > 0) {
document.getElementById('topLeftFrame').style.width = '100%';
} else {
document.getElementById('topLeftFrame').style.width = '50%';
}
}
html,
body {
height: 98%;
}
.page-container {
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: row;
resize: vertical;
border: 1px solid #000;
overflow: hidden;
}
.container-top {
height: 80%;
}
.container-bottom {
flex: 1 1;
overflow: hidden;
}
.container-left {
width: 30%;
border: 1px solid #000;
resize: horizontal;
overflow: hidden;
}
.container-right {
flex: 1 1;
height: 100%;
border: 1px solid #000;
overflow: hidden;
display: flex;
}
.frame-right {
flex: 1 1;
}
.frame-bottom {
flex: 1 1 100%;
border: 1px solid #000;
}
<html>
<body class="page-container">
<div class="container container-top" id="topFrame">
<div class="container-left" id="topLeftFrame">
<button onclick="toggleBottom()">Toggle Bottom</button>
<button onclick="toggleRight()">Toggle Right</button>
</div>
<div class="container-right" id="topRightFrame" >
<iframe src="https://stackoverflow.com" class="frame-right">
</iframe>
</div>
</div>
<div class="container container-bottom" id="bottomFrame">
<iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
</div>
</body>
</html>
Option 2
Using flex and using some scripting we should be able to make the whole border draggable. This is inspired from the answer in https://stackoverflow.com/a/53220241/2772300
const topRightFrame = document.getElementById("topRightFrame");
const topLeftFrame = document.getElementById("topLeftFrame");
const bottomFrame = document.getElementById("bottomFrame");
const topFrame = document.getElementById("topFrame");
const borderSize = 4;
function toggleBottom() {
if (bottomFrame.clientHeight > borderSize) {
topFrame.style.height = '100%';
} else {
topFrame.style.height = '80%';
}
}
function toggleRight() {
if (topRightFrame.clientWidth > borderSize) {
topLeftFrame.style.width = '100%';
} else {
topLeftFrame.style.width = '50%';
}
}
let mousePosition;
function resizeHorizontal(e){
const dx = mousePosition - e.x;
mousePosition = e.x;
topLeftFrame.style.width = (parseInt(getComputedStyle(topLeftFrame, '').width) - dx) + "px";
}
topRightFrame.addEventListener("mousedown", function(e){
if (e.offsetX < borderSize) {
mousePosition = e.x;
document.addEventListener("mousemove", resizeHorizontal, false);
}
}, false);
document.addEventListener("mouseup", function(){
document.removeEventListener("mousemove", resizeHorizontal, false);
}, false);
function resizeVertical(e){
const dy = mousePosition - e.y;
mousePosition = e.y;
topFrame.style.height = (parseInt(getComputedStyle(topFrame, '').height) - dy) + "px";
}
bottomFrame.addEventListener("mousedown", function(e){
if (e.offsetY < borderSize) {
mousePosition = e.y;
document.addEventListener("mousemove", resizeVertical, false);
}
}, false);
document.addEventListener("mouseup", function(){
document.removeEventListener("mousemove", resizeVertical, false);
}, false);
html,
body {
height: 98%;
}
.page-container {
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: row;
overflow: hidden;
}
.container-top {
height: 80%;
}
.container-left {
width: 50%;
overflow: hidden;
height: 100%;
}
.container-right {
flex: 1 1;
height: 100%;
overflow: hidden;
display: flex;
padding-left: 4px;
background-color: #ccc;
cursor: ew-resize;
}
.frame-right {
flex: 1 1;
}
.container-bottom {
flex: 1 1;
overflow: hidden;
padding-top: 4px;
background-color: #ccc;
cursor: ns-resize;
}
.frame-bottom {
flex: 1 1 100%;
}
iframe {
border: 0;
}
<html>
<body class="page-container">
<div class="container container-top" id="topFrame">
<div class="container-left" id="topLeftFrame">
<button onclick="toggleBottom()">Toggle Bottom</button>
<button onclick="toggleRight()">Toggle Right</button>
</div>
<div class="container-right" id="topRightFrame" >
<iframe src="https://stackoverflow.com" class="frame-right">
</iframe>
</div>
</div>
<div class="container container-bottom" id="bottomFrame">
<iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
</div>
</body>
</html>
Have you looked a Golden Layout to do the resizing? You could then place iframes inside to match the size of the containing div.
Sorry this not a more complete answer, but though this might be an area worth exploring that is not likely to come up.
I have fixed sidebar which should scroll along with main content and stop at certain point when I scroll down. And vise versa when I scroll up.
I wrote script which determines window height, scrollY position, position where sidebar should 'stop'. I stop sidebar by adding css 'bottom' property. But I have 2 problems with this approach:
When sidebar is close to 'pagination' where it should stop, it suddenly jumps down. When I scroll up it suddenly jumps up.
When I scroll page, sidebar moves all the time
Here's my code. HTML:
<div class="container">
<aside></aside>
<div class="content">
<div class="pagination"></div>
</div>
<footer></footer>
</div>
CSS:
aside {
display: flex;
position: fixed;
background-color: #fff;
border-radius: 4px;
transition: 0s;
transition: margin .2s, bottom .05s;
background: orange;
height: 350px;
width: 200px;
}
.content {
display: flex;
align-items: flex-end;
height: 1000px;
width: 100%;
background: green;
}
.pagination {
height: 100px;
width: 100%;
background: blue;
}
footer {
height: 500px;
width: 100%;
background: red;
}
JS:
let board = $('.pagination')[0].offsetTop;
let filterPanel = $('aside');
if (board <= window.innerHeight) {
filterPanel.css('position', 'static');
filterPanel.css('padding-right', '0');
}
$(document).on('scroll', function () {
let filterPanelBottom = filterPanel.offset().top + filterPanel.outerHeight(true);
let bottomDiff = board - filterPanelBottom;
if(filterPanel.css('position') != 'static') {
if (window.scrollY + window.innerHeight - (bottomDiff*2.6) >= board)
filterPanel.css('bottom', window.scrollY + window.innerHeight - board);
else
filterPanel.css('bottom', '');
}
});
Here's live demo on codepen
Side bar is marked with orange background and block where it should stop is marked with blue. Than you for your help in advance.
I solved my problem with solution described here
var windw = this;
let board = $('.pagination').offset().top;
let asideHeight = $('aside').outerHeight(true);
let coords = board - asideHeight;
console.log(coords)
$.fn.followTo = function ( pos ) {
var $this = this,
$window = $(windw);
$window.scroll(function(e){
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed',
top: 0
});
}
});
};
$('aside').followTo(coords);
And calculated coordinates as endpoint offset top - sidebar height. You can see solution in my codepen
If you take a look at KIOSK WEBSITE HERE they have the 'WE ARE OPEN" circular type in javascript (I know how to do that) but what I don't know is how to achieve that when scrolling. Like how does the text move when scrolling up or down. How do you get that in HTML/CSS/JS ?
View the code I worked on here https://codepen.io/noel_emmanuel/pen/WJxRZW
HTML:
<!--just a container used to position in the page-->
<div class="container">
<!--the holders/targets for the text, reuse as desired-->
<div class="circTxt" id="test"></div>
</div>
<!--I told you it was simple! :)-->
CSS:
body {
background: #111;
}
.container {
/*centers in the container*/
text-align: center;
}
div.circTxt {
/*allows for centering*/
display: inline-block;
/*adjust as needed*/
margin-bottom: 128px;
color: whitesmoke;
}
JS:
function circularText(txt, radius, classIndex) {
txt = txt.split(""),
classIndex = document.getElementsByClassName("circTxt")[classIndex];
var deg = 360 / txt.length,
origin = 0;
txt.forEach((ea) => {
ea = `<p style='height:${radius}px;position:absolute;transform:rotate(${origin}deg);transform-origin:0 100%'>${ea}</p>`;
classIndex.innerHTML += ea;
origin += deg;
});
}
circularText("WE ARE OPEN", 100, 0);
OPEN FOR SUGGESTIONS.
You could rotate this on a scroll event. This simply rotates the div depending on how far from the top of the page you have scrolled.
I added a height and width to the text, as well as positioned it fixed to see the effect.
function circularText(txt, radius, classIndex) {
txt = txt.split(""),
classIndex = document.getElementsByClassName("circTxt")[classIndex];
var deg = 360 / txt.length,
origin = 0;
txt.forEach((ea) => {
ea = `<p style='height:${radius}px;position:absolute;transform:rotate(${origin}deg);transform-origin:0 100%'>${ea}</p>`;
classIndex.innerHTML += ea;
origin += deg;
});
}
circularText("WE ARE OPEN", 100, 0);
$(document).ready(function(){
$(window).scroll(function(e){
rotateText();
});
function rotateText(){
var scrolled = $(window).scrollTop();
$('div.circTxt').css('transform','rotate('+scrolled+'deg)');
}
});
body {
background: #111;
}
.container {
/*centers in the container*/
text-align: center;
height: 4000px;
}
div.circTxt {
/*allows for centering*/
display: inline-block;
/*adjust as needed*/
margin-bottom: 128px;
color: whitesmoke;
position: fixed;
height: 200px;
width: 200px;
transform-origin: 0% 59%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--just a container used to position in the page-->
<div class="container">
<!--the holders/targets for the text, reuse as desired-->
<div class="circTxt" id="test"></div>
</div>
<!--I told you it was simple! :)-->
What I want:
| A | | B | | C |
^ ^
When you move the handles left and right A, B, and C resize accordingly
| A | | B | | C |
What I have is the || between B and C sliding, but not resizing B and all I get on the other one is the resize cursor. Basically C is a curtain and covers A and B. I did get min size working for C.
| A | C |
I broke somebody else's perfectly good code to get this far:
var isResizing = false,
who='',
lastDownX = 0;
$(function () {
var container = $('#container'),
left = $('#left'),
right = $('#right'),
middle = $('#middle'),
hand2 = $('#hand2'),
handle = $('#handle');
handle.on('mousedown', function (e) {
isResizing = true;
who=e.target.id;
lastDownX = e.clientX;
});
$(document).on('mousemove', function (e) {
var temp, min;
// we don't want to do anything if we aren't resizing.
if (!isResizing)
return;
min=container.width() * 0.1;
temp = container.width() - (e.clientX - container.offset().left);
if (temp < min)
temp = min;
if (who == 'handle')
right.css('width', temp);
if (who == 'hand2')
left.css('width', temp);
}).on('mouseup', function (e) {
// stop resizing
isResizing = false;
});
});
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
/* Disable selection so it doesn't get annoying when dragging. */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: moz-none;
-ms-user-select: none;
user-select: none;
}
#container #left {
width: 40%;
height: 100%;
float: left;
background: red;
}
#container #middle {
margin-left: 40%;
height: 100%;
background: green;
}
#container #right {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 200px;
background: rgba(0, 0, 255, 0.90);
}
#container #handle {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
#container #hand2 {
position: absolute;
left: 39%;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
<div id="container">
<!-- Left side -->
<div id="left"> This is the left side's content!</div>
<!-- middle -->
<div id="middle">
<div id="hand2"></div> This is the middle content!
</div>
<!-- Right side -->
<div id="right">
<!-- Actual resize handle -->
<div id="handle"></div> This is the right side's content!
</div>
</div>
Been playing with it here: https://jsfiddle.net/ju9zb1he/5/
I was looking for a solution that required less extensive CSS. It does have one minor bug(FIXED), but hopefully this should get you started. Here is a DEMO.
Also I aimed to use DOM Traversal methods like .next() and .prev() that way it wouldn't be so attribute dependent, and would be easily reusable if you needed a feature like this multiple times on a page.
Edit - Further Explanation
The idea here is onClick of a .handle we want to gather the total width (var tWidth) of the .prev() and .next() divs relative to the .handle in the DOM. We can then use the start mouse position (var sPos) to substract the amount of pixels we've moved our mouse (e.pageX). Doing so gives us the correct width that the .prev() div should have on mousemove. To get the width of the .next() div we need only to subtract the width of the .prev() div from the total width (var tWidth) that we stored onClick of the .handle. Hope this helps! Let me know if you have any further questions, however I will likely be unavailable till 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){ // Added an additional condition here below
var cPos = sPos - e.pageX;
handle.prev().width((tWidth / 2) - cPos); // This was part of the bug...
handle.next().width(tWidth - handle.prev().width());
// Added an update to sPos here below
}
});
Edit
The bug was caused by 2 things.
1) On mousemove we were dividing the total width by two, instead of an updated mouse offset.
2) The sPos was not updating on mousemove, and stayed a static number based off of the click location.
Resolution
Update the sPos on mousemove that way the mouse offset is accurately based off of the previous mousemove position, rather than the click position. When this is done we can then subtract the .next() div's width from the total width. Then we subtract our current mouse position from the remaining width. The fiddle has been updated as well.
$('.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
Added an additional condition on mousemove to prevent the drag from exceeding the total width (var tWidth).
Can you please explain what you're trying to accomplish?
I don't believe you need to use position: absolute. The premise of absolute positioning is to override the margin and padding imposed on an element by its parent.
You don't need to do this, all elements have relative positioning by default which makes them push eachother around and don't allow overlapping.
I'm probably missing something, but I think this is what you want with nothing but some very basic CSS: http://jsfiddle.net/3bdoazpk/
<div class='first'>
asdf
</div><div class='second'>
dasdf
</div><div class='third'>
sadf
</div>
body {
margin: 0;
}
div {
display: inline-block;
height: 100%;
}
.first, .third {
width: 40%;
}
.first {
background-color: red;
}
.second {
background-color: blue;
width: 20%;
}
.third {
background-color: green;
}