JavaScript和vue实现左右两栏,中间拖动按钮可以拖动左右两边的宽度

JavaScript实现:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <title>拖动效果</title>
  <style>
body, html {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: Arial, sans-serif;
}

.container {
  display: flex;
  height: 100vh;
  position: relative;
}

.left-column, .right-column {
  flex-grow: 1;
  padding: 20px;
  box-sizing: border-box;
}

.left-column {
  background-color: #f0f0f0;
}

.right-column {
  background-color: #e0e0e0;
}

.divider {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 10px;
  cursor: ew-resize;
  background-color: #ccc;
  z-index: 1;
  left: calc(33.333% - 5px); /* 初始位置设为 33.333% 宽度减去一半的分割线宽度 */
}

.handle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  background-color: #666;
  border-radius: 50%;
  cursor: ew-resize;
}


  </style>
</head>
<body>
  <div class="container">
    <div class="left-column">
      <h2>Left Column</h2>
      <p>This is the left column.</p>
    </div>
    <div class="divider" id="divider">
      <span class="handle"></span>
    </div>
    <div class="right-column">
      <h2>Right Column</h2>
      <p>This is the right column.</p>
    </div>
  </div>

  <script>
// scripts.js

document.addEventListener('DOMContentLoaded', function() {
  const divider = document.getElementById('divider');
  let isDragging = false;
  let initialX = 0;
  let initialWidth = 0;
  const container = document.querySelector('.container');

  // 设置初始位置
  const initialLeftPosition = container.offsetWidth * (1/3) - divider.offsetWidth / 2;
  divider.style.left = `${initialLeftPosition}px`;
  document.querySelector('.left-column').style.width = `${initialLeftPosition + divider.offsetWidth}px`;
  document.querySelector('.right-column').style.width = `${container.offsetWidth - (initialLeftPosition + divider.offsetWidth)}px`;

  // 监听鼠标按下事件
  divider.addEventListener('mousedown', function(e) {
    isDragging = true;
    initialX = e.clientX;
    initialWidth = divider.offsetLeft;
    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', stopDragging);
  });

  // 监听鼠标移动事件
  function drag(e) {
    if (!isDragging) return;
    const delta = e.clientX - initialX;
    const newLeftPosition = initialWidth + delta;
    const maxWidth = container.offsetWidth - divider.offsetWidth;
    const minWidth = 150; // 设定最小宽度
    const maxWidthLeft = maxWidth / 2; // 左侧最大宽度为一半的容器宽度
    const maxWidthRight = maxWidth / 2; // 右侧最大宽度为一半的容器宽度

    if (newLeftPosition >= minWidth && newLeftPosition <= maxWidthLeft) {
      divider.style.left = `${newLeftPosition}px`;
      document.querySelector('.left-column').style.width = `${newLeftPosition + divider.offsetWidth}px`;
      document.querySelector('.right-column').style.width = `${maxWidth - newLeftPosition}px`;
    }
  }

  // 监听鼠标抬起事件
  function stopDragging() {
    isDragging = false;
    document.removeEventListener('mousemove', drag);
    document.removeEventListener('mouseup', stopDragging);
  }
});
  </script>
</body>
</html>

Vue2实现:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue 2拖动效果</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <style>
/* styles.css */

body, html {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: Arial, sans-serif;
}

.container {
  display: flex;
  height: 100vh;
  position: relative;
}

.left-column, .right-column {
  flex-grow: 1;
  padding: 20px;
  box-sizing: border-box;
}

.left-column {
  background-color: #f0f0f0;
}

.right-column {
  background-color: #e0e0e0;
}

.divider {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 10px;
  cursor: ew-resize;
  background-color: #ccc;
  z-index: 1;
  left: 0; /* 调整初始位置为 0 */
}

.handle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  background-color: #666;
  border-radius: 50%;
  cursor: ew-resize;
}
  </style>
</head>
<body>
  <div id="app">
    <div class="container">
      <div class="left-column" :style="{width: leftColumnWidth + 'px'}">
        <h2>Left Column</h2>
        <p>This is the left column.</p>
      </div>
      <div class="divider" ref="divider" @mousedown="startDragging">
        <span class="handle"></span>
      </div>
      <div class="right-column" :style="{width: rightColumnWidth + 'px'}">
        <h2>Right Column</h2>
        <p>This is the right column.</p>
      </div>
    </div>
  </div>
<script>

new Vue({
  el: '#app',
  data: {
    leftColumnWidth: 300,
    rightColumnWidth: 0,
    isDragging: false,
    initialX: 0,
    initialWidth: 0,
    containerWidth: 0,
    minWidth: 150, // 最小宽度
    maxWidth: 0, // 最大宽度
  },
  mounted() {
    this.containerWidth = document.querySelector('.container').clientWidth;
    this.maxWidth = Math.floor(this.containerWidth / 2) - 10; // 减去分割线的宽度
    this.rightColumnWidth = this.containerWidth - this.leftColumnWidth - 10;
    document.addEventListener('mousemove', this.drag);
    document.addEventListener('mouseup', this.stopDragging);

    // 设置初始位置
    const divider = this.$refs.divider;
    divider.style.left = `${this.leftColumnWidth}px`;
  },
  methods: {
    startDragging(e) {
      this.isDragging = true;
      this.initialX = e.clientX;
      this.initialWidth = this.leftColumnWidth;
    },
    drag(e) {
      if (!this.isDragging) return;
      const delta = e.clientX - this.initialX;
      const newLeftWidth = this.initialWidth + delta;

      if (newLeftWidth >= this.minWidth && newLeftWidth <= this.maxWidth) {
        this.leftColumnWidth = newLeftWidth;
        this.rightColumnWidth = this.containerWidth - newLeftWidth - 10;

        // 更新 divider 的位置
        const divider = this.$refs.divider;
        divider.style.left = `${this.leftColumnWidth}px`;
      }
    },
    stopDragging() {
      this.isDragging = false;
    }
  }
});
</script>
</body>
</html>
相关推荐
酷酷的阿云8 分钟前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:1379712058711 分钟前
web端手机录音
前端
齐 飞16 分钟前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
神仙别闹33 分钟前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
aPurpleBerry1 小时前
JS常用数组方法 reduce filter find forEach
javascript
GIS程序媛—椰子1 小时前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_0012 小时前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端2 小时前
Content Security Policy (CSP)
前端·javascript·面试
乐闻x2 小时前
ESLint 使用教程(一):从零配置 ESLint
javascript·eslint
木舟10092 小时前
ffmpeg重复回听音频流,时长叠加问题
前端