js实现上下拖动改变父div的高度,左右上下拖动动态分割孩子的宽高
实现父 p 里面 左右,上下动态分割 p,并上下改变父 p 的高度,并且宽和高都是按百分比(如图) 。
2. 实现原理
2.1 父布局
首先一个父 p 为 hj-wrap,相对定位 。 一个改变父 p 高度的 arrow,用于上下拖动 , 不能占有位置,所以要绝对定位,并定位到最右下角。 上下拖动的 arrow,当上拖动时,arrow 的父 p 的高度变小,当下拖动时,arrow 的父 p 的高度变大。
2.2 横向布局
横 向
横 向 2
横 向 3
横 向 4
横 向 5
每一个横向的 p 为 hj-transverse-split-p 并相对定位,里面有一个拖动改变左右的 label 为 hj-transverse-split-label ,不能占有位置,所以要绝对定位,并定位到最右边并高为 100%,最后一个横向的 p 不用 hj-transverse-split-label 。 拖动改变左右的 label 时,向左时,label 的父 p 的宽变小,label 的父 p 相邻的 右边的 p 宽度变大。
2.3 竖向布局
上
中
下
每一个横向的 p 为 hj-vertical-split-p 并相对定位,里面有一个拖动改变左右的 label 为 hj-vertical-split-label ,不能占有位置,所以要绝对定位,并定位到最下边并宽为 100%,最后一个竖向的 p 不用再放 hj-vertical-split-label 的 label 。 拖动改变上下的 label 时,向上时,label 的父 p 的高度变小,label 的父 p 相邻的下边的 p 高度变大。
3. js 实现
代码:
/**
* name: split.js
* author: biaochen
* date: 2018-12-26
*
*/
$(function() {
//鼠标横向、竖向、和改变父高度的上下 操作对象
var thistransverseobject, thisverticalobject, thisarrowobject;
//文档对象
var doc = document;
//横向分割栏
var transverselabels = $(".hj-wrap").find(".hj-transverse-split-label");
//竖向分割栏
var verticallabels = $(".hj-wrap").find(".hj-vertical-split-label");
// 改变父高度的 箭头 p
var parentarrow = $(".hj-wrap").find(".arrow");
// 设置宽
function setwidth(type) {
if (type === "init") {
var length = $(".hj-wrap").length;
if (length > 0) {
for (var i = 0; i < length; i++) {
var width = $($(".hj-wrap")[i])[0].offsetwidth;
var hjdivnums = $($(".hj-wrap")[i]).children(".hj-transverse-split-p");
// var defaultwidth = math.floor(100 / hjdivnums.length);
var defaultwidth = math.floor(width / hjdivnums.length);
$($(".hj-wrap")[i])
.children(".hj-transverse-split-p")
.width(defaultwidth + "px");
// .width(defaultwidth + "%");
}
}
} else {
// 设置百分比
var transversedivs = $(".hj-transverse-split-p")
var widthlength = transversedivs.length
for (var i = 0; i < widthlength; i++) {
var width = $(transversedivs[i]).width();
var parentwidth = $(transversedivs[i])
.parent()
.width();
var rate = (width / parentwidth) * 100 + "%";
$(transversedivs[i]).css({ width: rate });
}
}
}
// 设置高
function setheight(type) {
if (type === "init") {
var verticalsparentdivs = $(".verticals");
var parentlengths = verticalsparentdivs.length;
for (var i = 0; i < parentlengths; i++) {
var parentheight = $(verticalsparentdivs[i]).height();
var childrennum = $(verticalsparentdivs[i]).children(
".hj-vertical-split-p"
).length;
var defaultheight = math.floor(parentheight / childrennum);
// var rate = math.floor((height / parentheight)* 100) + '%'
var defaultheight = math.floor(100 / childrennum);
$(verticalsparentdivs[i])
.children(".hj-vertical-split-p")
.height(defaultheight + "%");
// .height(defaultheight + "px");
}
} else {
// 设置百分比
var verticalsdivs = $(".hj-vertical-split-p");
var heightlength = verticalsdivs.length;
for (var i = 0; i < heightlength; i++) {
var height = $(verticalsdivs[i]).height();
var parentheight = $(verticalsdivs[i])
.parent()
.height();
var rate = (height / parentheight) * 100 + "%";
$(verticalsdivs[i]).css({ height: rate });
}
}
}
setwidth('init')
setheight("init");
//定义一个对象
function pointerobject() {
this.el = null; //当前鼠标选择的对象
this.clickx = 0; //鼠标横向初始位置
this.clicky = 0; //鼠标竖向初始位置
this.transversedragging = false; //判断鼠标可否横向拖动
this.verticaldragging = false; //判断鼠标可否竖向拖动
}
//横向分隔栏绑定事件
transverselabels.bind("mousedown", function(e) {
thistransverseobject = new pointerobject();
thistransverseobject.transversedragging = true; //鼠标可横向拖动
thistransverseobject.el = this;
thistransverseobject.clickx = e.pagex; //记录鼠标横向初始位置
});
//竖向分隔栏绑定事件
verticallabels.bind("mousedown", function(e) {
//console.log("mousedown");
thisverticalobject = new pointerobject();
thisverticalobject.verticaldragging = true; //鼠标可竖向拖动
thisverticalobject.el = this;
thisverticalobject.clicky = e.pagey; //记录鼠标竖向初始位置
});
//上下绑定事件
parentarrow.bind("mousedown", function(e) {
//console.log("mousedown");
thisarrowobject = new pointerobject();
// thisarrowobject.transversedragging = true; //鼠标可横向拖动
thisarrowobject.verticaldragging = true; //鼠标可竖向拖动
thisarrowobject.el = this;
thisarrowobject.clicky = e.pagey; //记录鼠标竖向初始位置
});
doc.onmousemove = function(e) {
//鼠标横向拖动
if (thistransverseobject != null) {
if (thistransverseobject.transversedragging) {
var changedistance = 0;
if (thistransverseobject.clickx >= e.pagex) {
//鼠标向左移动
changedistance =
number(thistransverseobject.clickx) - number(e.pagex);
if (
$(thistransverseobject.el)
.parent()
.width() -
changedistance <
20
) {} else {
$(thistransverseobject.el)
.parent()
.width(
$(thistransverseobject.el)
.parent()
.width() - changedistance
);
$(thistransverseobject.el)
.parent()
.next()
.width(
$(thistransverseobject.el)
.parent()
.next()
.width() + changedistance
);
thistransverseobject.clickx = e.pagex;
$(thistransverseobject.el).offset({ left: e.pagex });
}
} else {
//鼠标向右移动
changedistance =
number(e.pagex) - number(thistransverseobject.clickx);
if (
$(thistransverseobject.el)
.parent()
.next()
.width() -
changedistance <
20
) {} else {
$(thistransverseobject.el)
.parent()
.width(
$(thistransverseobject.el)
.parent()
.width() + changedistance
);
$(thistransverseobject.el)
.parent()
.next()
.width(
$(thistransverseobject.el)
.parent()
.next()
.width() - changedistance
);
thistransverseobject.clickx = e.pagex;
$(thistransverseobject.el).offset({ left: e.pagex });
}
}
$(thistransverseobject.el).width(2);
}
}
//鼠标竖向拖动
if (thisverticalobject != null) {
if (thisverticalobject.verticaldragging) {
var changedistance = 0;
if (thisverticalobject.clicky >= e.pagey) {
//鼠标向上移动
changedistance = number(thisverticalobject.clicky) - number(e.pagey);
if (
$(thisverticalobject.el)
.parent()
.height() -
changedistance <
20
) {} else {
$(thisverticalobject.el)
.parent()
.height(
$(thisverticalobject.el)
.parent()
.height() - changedistance
);
$(thisverticalobject.el)
.parent()
.next()
.height(
$(thisverticalobject.el)
.parent()
.next()
.height() + changedistance
);
thisverticalobject.clicky = e.pagey;
$(thisverticalobject.el).offset({ top: e.pagey });
}
} else {
//鼠标向下移动
changedistance = number(e.pagey) - number(thisverticalobject.clicky);
if (
$(thisverticalobject.el)
.parent()
.next()
.height() -
changedistance <
20
) {} else {
$(thisverticalobject.el)
.parent()
.height(
$(thisverticalobject.el)
.parent()
.height() + changedistance
);
$(thisverticalobject.el)
.parent()
.next()
.height(
$(thisverticalobject.el)
.parent()
.next()
.height() - changedistance
);
thisverticalobject.clicky = e.pagey;
$(thisverticalobject.el).offset({ top: e.pagey });
}
}
$(thisverticalobject.el).height(2);
}
}
// 改变父的 高度
if (thisarrowobject != null) {
//鼠标竖向拖动
if (thisarrowobject.verticaldragging) {
var changedistance = 0;
if (thisarrowobject.clicky >= e.pagey) {
//鼠标向上移动
changedistance = number(thisarrowobject.clicky) - number(e.pagey);
if (
$(thisarrowobject.el)
.parent()
.height() -
changedistance <
50
) {} else {
$(thisarrowobject.el)
.parent()
.height(
$(thisarrowobject.el)
.parent()
.height() - changedistance
);
thisarrowobject.clicky = e.pagey;
$(thisarrowobject.el).offset({ bottom: e.pagey });
}
} else {
//鼠标向下移动
changedistance = number(e.pagey) - number(thisarrowobject.clicky);
$(thisarrowobject.el)
.parent()
.height(
$(thisarrowobject.el)
.parent()
.height() + changedistance
);
thisarrowobject.clicky = e.pagey;
$(thisarrowobject.el).offset({ bottom: e.pagey });
}
$(thisarrowobject.el).height(10);
}
}
};
$(doc).mouseup(function(e) {
setheight("setheight");
setwidth("setwidth");
// 鼠标弹起时设置不能拖动
if (thistransverseobject != null) {
thistransverseobject.transversedragging = false;
thistransverseobject = null;
}
if (thisverticalobject != null) {
thisverticalobject.verticaldragging = false;
thisverticalobject = null;
}
if (thisarrowobject != null) {
thisarrowobject.verticaldragging = false;
thisarrowobject = null;
}
e.cancelbubble = true;
});
});
4. 完整代码与效果
效果图:
项目地址:https://github.com/biaochenxuying/split
效果体验地址: https://biaochenxuying.github.io/split/index.html
初始代码是从网上来的,不过网上的并不完整,父 p 的高也不能改变,并且孩子的宽高并不是百分比的,布局也并不合理,所以修改成这样子。