JSFiddle - React, Tailwind, and code Playground
by tonyleeper
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js"></script>
<div class="panel-splitter" data-bind="panelSplitter: {
showPanelLeftLabel: 'SHOW LEFTY',
showPanelRightLabel: 'SHOW RIGHTY',
leftPanelDefaultWidthPercentage: 60,
snapToThreshold: 100
}">
<div class="column-left">
<div class="content-panel">
column1
</div>
</div>
<div class="drag-handle">
<div class="snap-left draghandle-snapper"><</div>
<div class="snap-right left-panel-snapper">></div>
<div class="grabber"></div>
</div>
<div class="column-right">
<div class="content-panel">
column2
</div>
</div>
</div>
CSS
* {
margin: 0;
padding: 0;
font-family: arial;
font-size: 12px;
}
body, html {
height: 100%;
}
.panel-splitter {
width: 100%;
height: 100%;
display: table;
-webkit-user-select: none;
}
.drag-handle {
position: relative;
width: 25px;
min-width: 25px;
max-width: 25px;
background-color: #f0f0f0;
border-left: 1px solid black;
border-right: 1px solid black;
cursor: ew-resize; /* or col-resize ? */
}
.panel-splitter > div {
display: table-cell;
}
.column-left, .column-right {
background-color: #e0e0e0;
overflow: hidden;
position: relative;
}
.content-panel {
position: absolute;
font-size: 100px;
}
.grabber {
width: 10px;
height: 40px;
background-color: blue;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
}
.drag-handle > .snap-left, .drag-handle > .snap-right {
cursor: pointer;
width: 20px;
height: 20px;
background-color: red;
position: absolute;
}
.left-panel-snapper {
left: -25px;
top: 5px;
}
.draghandle-snapper {
left: 50%;
top: 5px;
-webkit-transform: translateX(-50%);
}
.showPanelLeftLabel, .showPanelRightLabel {
display: block;
position: absolute;
left: 50%;
top: 30px;
-webkit-transform-origin: 0 0;
-webkit-transform: rotate(90deg) translate(0, -50%);
white-space: nowrap;
}
JavaScript
/**
panel splitter knockout binding
*/
/**
Custom plugin for drag support, including support for touch devices
@param {function} onDrag a callback to invoke on drag
@param {function} onDragStart an optional function to run on dragStart to determine if dragging should begin
@param {function} onDragEnd an optional function to run on dragEnd
*/
(function ($) {
var normalizeEvent = function(event) {
// "normalize" the event so that the passed in drag handler doesn't have to worry about
if ('ontouchstart' in window || navigator.msMaxTouchPoints) {
event.pageX = event.originalEvent.touches[0].pageX;
event.pageY = event.originalEvent.touches[0].pageY;
event.clientX = event.originalEvent.touches[0].clientX;
event.clientY = event.originalEvent.touches[0].clientY;
}
return event;
};
$.fn.draggable = function (onDrag, onDragStart, onDragEnd) {
var $document = $(document);
return this.each(function () {
var element = this;
$(this).on("mousedown touchstart", function (event) {
event = normalizeEvent(event);
if (typeof onDragStart === "function") {
if (!onDragStart(event)) {
return false;
}
}
element.dragging = true;
$(element).addClass("dragging");
// prevent scrolling on touch devices
if (event.type === 'touchstart') {
return false;
}
return true;
});
$document.on("mouseup touchend", function (event) {
if (element.dragging) {
element.dragging = false;
$(element).removeClass("dragging");
}
if (typeof onDragEnd === "function") {
...