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

news2024/9/22 13:30:52

JavaScript实现:

<!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实现:

<!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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1974010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytest测试框架之http协议接口测试

1 接口测试 日常测试中接口测试是一项重要的工作&#xff0c;尤其是http协议的接口测试更加普遍,比如一些常用的测试框架或者工具&#xff08;robotframework框架&#xff0c;testng框架&#xff0c;postman等&#xff09;都支持http接口的测试&#xff0c;而这节内容主要介绍…

函数:全局,局部和静态变量

文章目录 &#x1f34a;自我介绍&#x1f34a;全局变量&#x1f34a;局部变量&#x1f34a;静态局部变量 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello,大家好&#x…

力扣SQL50 餐馆营业额变化增长 子连接

Problem: 1321. 餐馆营业额变化增长 &#x1f468;‍&#x1f3eb; 参考题解 Code select a.visited_on,sum(b.amount) as amount, round(sum(b.amount) / 7,2) as average_amount from (select distinct visited_on from customer) a join customer bon datediff(a.visited…

window安装elasticsearch和可视化界面kibana

ElasticSearch 官网下载zip安装包并解压 Elasticsearch&#xff1a;官方分布式搜索和分析引擎 | Elastic 修改配置文件 改选项是指定ssl访问还是普通http访问 不改的话使用http访问不了&#xff0c;得使用https 浏览器访问 localhost:9200 Kibana Download Kibana Free |…

MySQL 将文件导入数据库(load data Statement)

前面我们介绍过如何用select…into outfile语句将SQL查询结果导出到文件&#xff1a; MySQL 将查询结果导出到文件&#xff08;select … into Statement&#xff09; MySQL同时也提供互补的功能&#xff0c;可以使用load data infile语句将文件中的数据加载到数据库中&#x…

Robot Operating System——Action通信机制的服务端

大纲 回调接受或者拒绝请求执行任务的回调终止任务回调 创建服务完整代码总结 在《Robot Operating System——Action通信机制概念及Client端》一文中&#xff0c;我们介绍了Action客户端的主要流程。本文我们将介绍Action服务端的编写。 回顾下Action的构成: 目标&#xff0…

cesium canvas广告牌

在有些业务中&#xff0c;对场景中的广告牌样式要求比较高&#xff0c;需要动态显示一些数据&#xff0c;这个时候&#xff0c;我们可以通过将复杂背景样式制作成图片&#xff0c;通过canvas绘制图片和动态数据&#xff0c;从而达到比较好的显示效果。 1 CanvasMarker 类封装 …

ICM-20948芯片详解(2)

接前一篇文章&#xff1a;ICM-20948芯片详解&#xff08;1&#xff09; 二、详述 ICM-20948是一款9轴运动跟踪设备&#xff0c;全部采用3x3x1mm QFN封装。ICM-20948是一个多芯片模块&#xff08;MCM&#xff09;&#xff0c;由集成在单个QFN封装中的两个管芯组成。一个芯片内装…

2024年【制冷与空调设备运行操作】考试技巧及制冷与空调设备运行操作考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 制冷与空调设备运行操作考试技巧考前必练&#xff01;安全生产模拟考试一点通每个月更新制冷与空调设备运行操作考试试题题目及答案&#xff01;多做几遍&#xff0c;其实通过制冷与空调设备运行操作作业模拟考试很简…

leetcode173. 二叉搜索树迭代器,注意vector中的size()的无符号整数类型,无符号整数和有符号整数的加减比大小有着种种大坑

leetcode173. 二叉搜索树迭代器 实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分…

【MySQL】全面剖析索引失效、回表查询与索引下推

1.索引失效的情况 以tb_user表举例&#xff0c;id为主键索引、name和phone字段上建立了一个普通索引&#xff0c;name和phone均为varchar类型。 索引列运算 当在 WHERE 子句或 JOIN 子句中对列使用函数或表达式时&#xff0c;索引会失效。 执行以下语句&#xff0c;可以发现执…

分布式事务原理

目录 第一节&#xff1a;分布式事务基础详细总结 1.1 事务的核心特性&#xff08;ACID&#xff09; 1.2 分布式事务的挑战 1.3 分布式事务的实现难点 1.4 分布式事务解决方案概览 图解&#xff1a;分布式事务的ACID特性 第二节&#xff1a;事务消息方案详细总结 2.1 事务…

AUTOSAR实战教程-使用DET来发现开发错误

2年之前因为在调试AUTOSAR存储协议栈的时候使用DET并没发现有用的信息,所以就武断下结论--这玩意没有用。活到老学到老吧,bug经历的多了,发现这玩意还挺有用的。说一下这个bug的背景。 在将时间同步报文改道CanTsync之后,由于这个AUTOSAR工具本身的问题以及配置工程师本身的…

SpringBoot校园社团场地租借平台开发-计算机毕业设计源码00746

摘 要 这个项目旨在开发一个基于SpringBoot 的校园社团场地租借平台&#xff0c;帮助学校社团更方便地租借校园内的场地。用户可以在平台上浏览不同场地的信息、预订场地、查看租借历史记录等。管理员可以管理场地信息、审批租借申请和生成报表统计等功能。通过该平台&#xff…

【大模型实战篇】搭建本地的隐私计算知识问答系统“密答”

1. 背景介绍 在之前分享的文章《基于开源大模型的问答系统本地部署实战教程》中&#xff0c;我们介绍了基于ollama实现本地问答系统的部署和使用。本文将基于ollama进一步实现本地垂直领域的问答系统搭建。ollama作为大模型的运行框架&#xff0c;可以提供大模型的使用接口…

Python 设计模式之建造者模式

文章目录 建造者模式中的简单版本逐渐复杂的问题建造者模式的实现 建造者模式中的经典版本 建造者&#xff08;builder&#xff09;模式属于创建型模式&#xff0c;建造者模式一般有两种类型的应用 建造者模式中的简单版本 逐渐复杂的问题 假设现在需要创建一个用户对象&…

如何提高小红书种草转化率

企业和品牌方想要在小红书上做种草推广一般分为图文种草和视频种草两种形式&#xff0c;而且小红书是一个完全可以依靠内容实现涨粉、变现、种草转化的平台&#xff01; 因为小红书是算法推荐制&#xff0c;将你的作品放在流量池中检测&#xff0c;满足要求就能进入下一个流量池…

Python酷库之旅-第三方库Pandas(061)

目录 一、用法精讲 236、pandas.Series.explode方法 236-1、语法 236-2、参数 236-3、功能 236-4、返回值 236-5、说明 236-6、用法 236-6-1、数据准备 236-6-2、代码示例 236-6-3、结果输出 237、pandas.Series.searchsorted方法 237-1、语法 237-2、参数 237-…

Linux 内核源码分析---插入和删除模块

模块是一种向 Linux 内核添加设备驱动程序、文件系统及其他组件的有效方法&#xff0c;不需编译新内核或重启系统。 模块具有如下优点&#xff1a; • 通过使用模块&#xff0c;内核发布者能够预先编译大量驱动程序&#xff0c;而不会致使内核映像的尺寸发生膨胀&#xff1b; …

PTA—基础编程题目集(7-18)

7-18 二分法求多项式单根 目录 题目描述 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 参考代码 总结 题目描述 输入在第1行中顺序给出多项式的4个系数a3​、a2​、a1​、a0​&#xff0c;在第2行中顺序给出区间端点a和b。题目保证多项式在给定区间…