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>
相关推荐
candyTong33 分钟前
一觉醒来,大模型就帮我排查完页面性能问题
前端·javascript·架构
魔术师Grace35 分钟前
我给 AI 做了场入职培训
前端·程序员
玩嵌入式的菜鸡1 小时前
网页访问单片机设备---基于mqtt
前端·javascript·css
前端一小卒2 小时前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
滑雪的企鹅.3 小时前
HTML头部元信息避坑指南大纲
前端·html
一拳不是超人3 小时前
老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌
前端·ai编程
阿丰资源4 小时前
SpringBoot+Vue实战:打造企业级在线文档管理系统
vue.js·spring boot·后端
excel5 小时前
如何解决 Nuxt DevTools 中关于 unstorage 包的报错
前端
Rust研习社5 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
C澒5 小时前
AI 生码 - API2Code:接口智能匹配与 API 自动化生码全链路设计
前端·低代码·ai编程