盒子拉伸拉扯 左右模式(上下模式待续):
这里咱们使用vue来操作,然后代码封装到mixin里面,引用的时候直接混入到需要的页面就行了,具体如何操作请看代码。
重点:必须是flex模式(display: flex;)
1. 创建mixin文件: drag.js(看你自己创建在哪里了, 我的在这: src/mixin/drag.js ),
export default {
data() {
return {
defaultDragArr: [{
// 目前只有 LR 模式;也就是left right; 左右拉扯模式
type: 'LR',
domClass: {
// 中间分割线的名字
resize: 'line-line',
// 左侧盒子的名字
left: 'box-left',
// 右侧盒子的名字
right: 'box-right',
// 父级的名字
box: 'box-father',
},
otherInfo: {
// 限制左边栏最低宽度
leftWidth: 324
}
}]
}
},
methods: {
// 处理参数 进行dom节点选中
handleBoxInfo(boxInfo) {
for (const key in boxInfo)
if (Object.hasOwnProperty.call(boxInfo, key))
boxInfo[key] = document.getElementsByClassName(boxInfo[key])
return boxInfo
},
// 左右拉伸盒子处理函数
dragControllerDiv(boxInfo, otherInfo, cb) {
const {
leftWidth: oLeftWidth
} = otherInfo;
const {
resize,
left,
right,
box
} = this.handleBoxInfo(JSON.parse(JSON.stringify(boxInfo)))
console.dir(left)
const getOffsetLeftAndClientWidth = arr => arr.map(dom => [
dom[0].offsetLeft || 0,
dom[0].clientWidth || 0
])
for (let i = 0; i < resize.length; i++) {
resize[i].onmousedown = (e) => {
const [
[leftOffset],
[, resizeWidth],
[rightLeftOffset, rightLeftWidth],
[boxLeftOffset]
] = getOffsetLeftAndClientWidth([left, resize, right, box])
// 父级盒子距离右侧屏幕的margin宽度
const rightAllMargin = window.innerWidth - rightLeftWidth - rightLeftOffset
const startX = e.clientX;
// 这里设置选中时候的 偏移 量
resize[i].left = resize[i].offsetLeft;
const boxWidth = window.innerWidth - box[i].clientWidth;
document.onmousemove = (e) => {
const endX = e.clientX;
// 分割线到左边的距离 + 鼠标位移了多少 - 屏幕宽度减去父级盒子宽度后的结果 - 左盒子到屏幕左侧的长度(此刻不会计算margin属性) + 分割线长度并居中恰好1.5倍(但是计算了右侧的margin则变为0.25倍)(确认拉伸时候鼠标对齐分割线) + 父级盒子距离左侧屏幕的margin宽度 + 父级盒子距离右侧屏幕的margin宽度
let leftWidth = resize[i].left + (endX - startX) - boxWidth - leftOffset + (resizeWidth * 0.25) + boxLeftOffset + rightAllMargin;
const maxT = box[i].clientWidth - (resize[i].offsetWidth - boxWidth);
if (leftWidth < oLeftWidth) leftWidth = oLeftWidth;
if (leftWidth > maxT - 50) leftWidth = maxT;
// resize[i].style.flex = leftWidth;
for (let j = 0; j < left.length; j++) {
left[j].style.flex = `0 0 ${leftWidth}px`;
right[j].style.flex = `1`;
}
}
this.eventOnmouseup(resize, i, cb)
return false;
}
}
},
eventOnmouseup(resize, i, cb) {
document.onmouseup = () => {
document.onmousemove = null;
document.onmouseup = null;
resize[i].releaseCapture && resize[i].releaseCapture();
cb && cb()
}
resize[i].setCapture && resize[i].setCapture();
},
initDrag(dragArr = this.defaultDragArr) {
/*
dragArr: [{ domClass, otherInfo, fn }]
type: LR // 左右拉扯(flex布局才能成功)
*/
const fn = item => ({
'LR': this.dragControllerDiv
} [item.type] || (() => {}));
this.$nextTick(() => dragArr.forEach((item) => fn(item)(item.domClass, item.otherInfo)))
}
},
}
2.使用:引入,然后调用初始化函数;
import dragMixin from "@/mixins/drag.js";
export default {
name: "Home",
mixins: [dragMixin],
created() {
// 第一种方式:直接初始化就行了,给你的左盒子、右盒子,父级盒子,拉扯线分别设置class名字(box-left, box-right, box-father, line-line),然后直接调用 this.initDrag()就行了。
// this.initDrag();
// 第二种方式:自定义名字。复制粘贴跟着改就行了。
this.initDrag([
{
type: "LR",
domClass: {
// 中间分割线的名字
resize: "line-line",
// 左侧盒子的名字
left: "box-left",
// 右侧盒子的名字
right: "box-right",
// 父级的名字
box: "box-father",
},
otherInfo: {
// 限制左边栏最低宽度
leftWidth: 324,
},
},
]);
},
};
3. 最后一步:修改盒子为flex模式
// 父级盒子
.box-father {
display: flex;
}
// 左侧盒子
.box-left {
// 这里设置你盒子的宽度的
flex: 0 0 400px;
}
// 右侧盒子
.box-right {
flex: 1;
}
示例:(随便创建个vue文件把以下代码扔进去就行了)
项目启动后的界面介绍:
代码:
<template>
<div class="home">
<!-- <img alt="Vue logo" src="../assets/logo.png" /> -->
<!-- <Map name="3" /> -->
<div class="grand flex">
<!-- 记住盒子上面不要弄padding,我没兼容padding、margin的情况。如果要加在父级上加,如果父级也是要拉扯的,那就创建个父级(原有父级变爷级) -->
<!-- 红色的是可以拖拽的线 -->
<div class="left-laowang" style="flex: 0 0 700px">
<div class="box-father flex">
<div class="box-postion"></div>
<div class="box-left"></div>
<div class="line line-line"></div>
<div class="box-right"></div>
</div>
</div>
<div class="line line-second"></div>
<div style="width: 200px;flex: 1;background: green;" class="box-second-father"></div>
</div>
</div>
</template>
<script>
// import Map from "@/components/map/second.vue";
import dragMixin from "@/mixins/drag.js";
export default {
name: "Home",
components: {
// Map,
},
mixins: [dragMixin],
created() {
this.initDrag([
{
type: "LR",
domClass: {
// 中间分割线的名字
resize: "line-line",
// 左侧盒子的名字
left: "box-left",
// 右侧盒子的名字
right: "box-right",
// 父级的名字
box: "box-father",
},
otherInfo: {
// 限制左边栏最低宽度
leftWidth: 324,
},
},
{
type: "LR",
domClass: {
// 中间分割线的名字
resize: "line-second",
// 左侧盒子的名字
left: "left-laowang",
// 右侧盒子的名字
right: "box-second-father",
// 父级的名字
box: "grand",
},
otherInfo: {
// 限制左边栏最低宽度
leftWidth: 324,
},
},
]);
},
};
</script>
<style scoped>
.line {
width: 30px;
height: 500px;
background: red;
cursor: w-resize;
}
.box-father {
border: 8px solid #000;
}
.line-second {
width: 10px;
background: red;
}
.flex {
display: flex;
}
.box-left {
flex: 0 0 400px;
height: 600px;
background: blue;
}
.box-right {
height: 600px;
background: green;
flex: 1;
}
.box-postion {
width: 200px;
height: 400px;
background: #ccc;
}
</style>
- 上下拉伸看看情况再弄吧,后续有需求则加到这个文章里面。
- 可以自己根据左右改成上下拉伸的,加个函数,再加个兼容type就行了。
- 非flex模式也可以搞,把设置flex属性那边改成 width 这些就行了。