admin管理员组文章数量:1291448
I want to make a vertically draggable division of two areas like the following.
I just want to modify a online example of draggable divs to be what I want. Finally, I got this. Can someone give me some hints to modify it?
JSFiddle Link : /
HTML
<div class="container">
<div class="area1">
Area 1
</div>
<div class="drag">
</div>
<div class="area2">
Area 2
</div>
</div>
CSS
.container {
position: fixed;
top: 51px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: #272822;
border: 1px solid #222;
// margin: 0 auto;
//display: inline-block;
}
.area1 {
position: absolute;
height: 100%;
width: 30%;
background-color: #ddd;
display: inline-block;
}
.drag {
position: fixed;
width: 5px;
height: 100%;
background-color: #444;
display: inline-block;
}
.area2 {
position: absolute;
right: 0;
height: 100%;
width: 30%;
background-color: #ddd;
display: inline-block;
}
JavaScript
$(document).ready(function() {
$('.drag').on('mousedown', function(e) {
var $area1 = $('.area1'),
$area2 = $('.area2'),
startWidth_a1 = $area1.width(),
startWidth_a2 = $area2.width(),
pX = e.pageX;
$(document).on('mouseup', function(e) {
$(document).off('mouseup').off('mousemove');
});
$(document).on('mousemove', function(me) {
var mx = (me.pageX - pX);
$area1.css({
width: startWidth_a1 - mx;
});
$area2.css({
//left: mx / 2,
width: startWidth_a2 - mx,
//top: my
});
});
});
});
I want to make a vertically draggable division of two areas like the following.
I just want to modify a online example of draggable divs to be what I want. Finally, I got this. Can someone give me some hints to modify it?
JSFiddle Link : https://jsfiddle/casperhongkong/omekvtka/14/
HTML
<div class="container">
<div class="area1">
Area 1
</div>
<div class="drag">
</div>
<div class="area2">
Area 2
</div>
</div>
CSS
.container {
position: fixed;
top: 51px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: #272822;
border: 1px solid #222;
// margin: 0 auto;
//display: inline-block;
}
.area1 {
position: absolute;
height: 100%;
width: 30%;
background-color: #ddd;
display: inline-block;
}
.drag {
position: fixed;
width: 5px;
height: 100%;
background-color: #444;
display: inline-block;
}
.area2 {
position: absolute;
right: 0;
height: 100%;
width: 30%;
background-color: #ddd;
display: inline-block;
}
JavaScript
$(document).ready(function() {
$('.drag').on('mousedown', function(e) {
var $area1 = $('.area1'),
$area2 = $('.area2'),
startWidth_a1 = $area1.width(),
startWidth_a2 = $area2.width(),
pX = e.pageX;
$(document).on('mouseup', function(e) {
$(document).off('mouseup').off('mousemove');
});
$(document).on('mousemove', function(me) {
var mx = (me.pageX - pX);
$area1.css({
width: startWidth_a1 - mx;
});
$area2.css({
//left: mx / 2,
width: startWidth_a2 - mx,
//top: my
});
});
});
});
Share
Improve this question
edited Feb 3, 2016 at 17:01
Joshua LI
asked Dec 26, 2015 at 15:31
Joshua LIJoshua LI
4,76311 gold badges44 silver badges75 bronze badges
2
- 6 I heavily remend split.js for this nathancahill.github.io/Split.js – Donnie D'Amato Commented Dec 27, 2015 at 14:38
- 2 link to split.js is dead. Now it's split.js – Danil Pyatnitsev Commented Feb 7, 2019 at 13:36
2 Answers
Reset to default 5For javascript, I would remend checking out a library, as this is slitghtly more plicated than just a few lines. @fauxserious gave Split.js as a fantastic example.
This is possible in pure HTML/CSS, though slightly limited, as discussed here.
HTML:
<div class="split-view">
<div class="resize-x panel" style="width: 216px;">
Panel A
</div>
<div class="panel">
Panel B
</div>
</div>
CSS:
/* Panels: */
.panel{
padding: 1em;
border-width: 6px;
border-style: solid;
height: 4em;
}
/* Resizing */
.resize-x {
resize: horizontal;
overflow: auto;
}
/* Split View */
.split-view {
margin: 1em 0;
width: 100%;
clear: both;
display: table;
}
.split-view .panel {
display: table-cell;
}
Based on @afischer's table-cell solution, here is an alternative one.
I have had to put accordions within the left side panel.
The sticky headers of the accordions require overflow to be visible,
while resize requires overflow to be anything but visible:
https://caniuse./#feat=css-sticky.
In the same time, I didn't need anything to place into the right side panel.
Thus, an overe was employing resize on the right panel, and rotating by 180 deg to get the dragable side to the middle, as well as this way the dragable corner relocated to the top (visible without scrolling).
Plus some highlight has been added to the dragable corner.
/* Panels: */
.panel{
padding: 1em;
border-width: 6px;
border-style: solid;
height: 4em;
}
/* Resizing */
.resize-x {
resize: horizontal;
overflow: auto;
transform: rotate(180deg);
border-right: solid gray 1px;
}
/* Split View */
.split-view {
margin: 1em 0;
width: 100%;
clear: both;
display: table;
}
.split-view .panel {
display: table-cell;
}
.resize-x::-webkit-resizer {
border-width: 8px;
border-style: solid;
border-color: transparent orangered orangered transparent;
}
<div class="split-view">
<div
class="panel"
style="width: 216px;">
Panel A
</div>
<div class="panel resize-x">
Panel B
</div>
</div>
Unfortunately there are two disappointing thing with the above:
- Firefox cannot handle the bination of table-cell and resize
- Only a corner of the grabber is responsive, which can even be scrolled out easily
Here is an other solution which also takes the above two problems into account
- without resize CSS property
- and with full height responsive grabber
It's a bination of a flexbox and an input:range slider.
The trick is that the pointer-event CSS property can be different
- on the slider's background
- and on its grabber.
The slider covers the entire view. The background of the slider is transparent for the events too (pointer-events: none), while the dragbar itself catches the events (pointer-events: auto).
It requires minor Javascript and because I've implemented the production version in Nuxt.js, I use Vue.js here, instead of vanilla JS.
new Vue({
el: '#vue',
data: {
windowWidth: null,
splitWidth: null,
},
mounted() {
this.windowWidth = window.innerWidth;
// For arbitrary initial position:
this.splitWidth = this.windowWidth * 2/3;
},
puted: {
flexRatio() {
return this.splitWidth / this.windowWidth;
}
}
})
body {
margin:0;
}
main {
display: flex;
width: 100%;
height: 100vh;
}
article {
display: flex;
}
section {
width: 100%;
height: 100%;
text-align: justify;
padding: 20px;
}
.section-left {
background-color: darkseagreen;
}
.section-right {
background-color: orangered;
}
#split-grabber {
pointer-events: none;
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
-webkit-appearance: none;
/* Safari allows dragging behind scroll bar.
We fix it by shrinking its width on the right side via both
its range value :max="windowWidth - 12"
and its width (CSS) width: calc(100% - 12px)
...synchronously */
width: calc(100% - 12px);
height: 100vh;
background: transparent;
outline: none;
margin: 0;
}
#split-grabber::-webkit-slider-thumb {
z-index: 1;
pointer-events: auto;
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 100vh;
background: lightgray;
box-shadow: 1px 2px 2px 0px gray;
cursor: col-resize;
}
#split-grabber::-moz-range-thumb {
z-index: 1;
pointer-events: auto;
-webkit-appearance: none;
appearance: none;
width: 5px;
height: 100vh;
background: lightgray;
box-shadow: 1px 2px 2px 0px gray;
cursor: col-resize;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<main id="vue">
<!-- Safari allows dragging behind scroll bar
We fix it by shrinking its width on the right side via both
its range value :max="windowWidth - 12"
and its width (CSS) width: calc(100% - 12px)
...synchronously -->
<input
id="split-grabber"
type="range"
v-model="splitWidth"
:max="windowWidth - 12"
>
<article
class="article"
:style="{'flex': flexRatio}"
>
<section
class="section section-left">
splitWidth:{{ splitWidth }}px<br>
“There was a rich man who always dressed in the finest clothes and lived in luxury every day.
And a very poor man named Lazarus, whose body was covered with sores, was laid at the rich man’s gate.
He wanted to eat only the small pieces of food that fell from the rich man’s table. And the dogs would e and lick his sores.
Later, Lazarus died, and the angels carried him to the arms of Abraham. The rich man died, too, and was buried.
In the place of the dead, he was in much pain. The rich man saw Abraham far away with Lazarus at his side.
He called, ‘Father Abraham, have mercy on me! Send Lazarus to dip his finger in water and cool my tongue, because I am suffering in this fire!’
</section>
</article>
<article
class="article"
:style="{'flex': 1-flexRatio}"
>
<section class="section section-right">
But Abraham said, ‘Child, remember when you were alive you had the good things in life, but bad things happened to Lazarus. Now he is forted here, and you are suffering.
Besides, there is a big pit between you and us, so no one can cross over to you, and no one can leave there and e here.’
The rich man said, ‘Father, then please send Lazarus to my father’s house.
I have five brothers, and Lazarus could warn them so that they will not e to this place of pain.’
But Abraham said, ‘They have the law of Moses and the writings of the prophets; let them learn from them.’
The rich man said, ‘No, father Abraham! If someone goes to them from the dead, they would believe and change their hearts and lives.’
But Abraham said to him, ‘If they will not listen to Moses and the prophets, they will not listen to someone who es back from the dead.’”
</section>
</article>
</main>
本文标签: javascriptVertically Draggable Division of Two AreasStack Overflow
版权声明:本文标题:javascript - Vertically Draggable Division of Two Areas - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741532522a2383839.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论