盒子拉伸拉扯(左右模式)

盒子拉伸拉扯(左右模式),第1张

盒子拉伸拉扯 左右模式(上下模式待续):

这里咱们使用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 这些就行了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1320262.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-11
下一篇 2022-06-11

发表评论

登录后才能评论

评论列表(0条)

保存