效果演示图

可拖拽的左、右侧边栏的使用情况还是挺多的,博客园后台管理的左侧边栏就可以拖拽哟!效果演示如下图:

HTML 代码

<div class="container">
<div class="left">
<div class="resize-bar"></div>
</div>
<div class="right">
<div class="resize-bar"></div>
</div>
</div>

CSS 代码

html,
body {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
padding: 0 !important;
margin: 0 !important;
} .container {
width: 80vw;
height: 100vh;
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
} .left {
position: relative;
width: 100px;
height: 100%;
background-color: rgb(160, 212, 233);
} .left .resize-bar {
position: absolute;
top: 0;
left: 100px;
width: 3px;
height: 100%;
opacity: 0;
} .left .resize-bar:hover {
cursor: col-resize;
opacity: 1;
background-color: rgb(210, 85, 50);
} .right {
position: relative;
width: 100px;
height: 100%;
background-color: rgb(36, 107, 214);
} .right .resize-bar {
position: absolute;
top: 0;
right: 100px;
width: 3px;
height: 100%;
opacity: 0;
} .right .resize-bar:hover {
cursor: col-resize;
opacity: 1;
background-color: rgb(211, 36, 164);
}

拖拽右侧边栏

往左拖拽

如上图,红色方框圈住的部分是 container 的区域,即鼠标移动范围和侧边栏宽度变化的计算区域。

右侧边栏边缘处在整个 container 的 x 坐标是整个 container 的宽度减去右侧边栏的宽度,命名为 startWidth。假如,container 的宽度是 1355 px,右侧边栏的宽度是 100 px,那么 startWidth = 1355px - 100px = 1255px。

鼠标拖拽右侧边栏的左边缘处往左移动,得到一个鼠标监听事件,获取其数值:event.pageX。假如 event.pageX = 1200px,那么右侧边栏应该移动:

\[moveStep = startWidth - event.pageX = 1255px - 1200px = 55px
\]

因此,右侧边栏由原来的 100px 增加 55px 得到的新宽度是 155px:

\[shiftWidth = moveStep + container.offsetLeft + right.clientWidth
\]
const container = document.querySelector(".container");
const right = document.querySelector(".right");
const rightResizeBar = document.querySelector(".right .resize-bar"); function moveRightBar(event) {
setTimeout(() => {
let startWidth = container.clientWidth - right.clientWidth;
let moveStep = startWidth - event.pageX;
let shiftWidth = moveStep + container.offsetLeft + right.clientWidth;
right.style.width = shiftWidth + "px";
rightResizeBar.style.right = shiftWidth + "px";
}, 200);
}

pageX、clientX 都是一样的数值,用哪个都可以。计算过程中有一个 container.offsetLeft,这是 container 距离浏览器窗口 x 为 0 处的左偏移量。因为 container 的宽度有可能不和浏览器窗口百分之百贴合,如果高和宽都小于浏览器窗口,且设置了垂直、水平居中,就存在左偏移量,即 offsetLeft。为了使侧边栏移动准确性,需要在 shiftWdith 计算的过程中加上container.offsetLeft

往右拖拽

startWidth 还是 1255px。鼠标拖拽右侧边栏的左边缘处往右移动,得到一个鼠标监听事件,获取其数值:event.pageX。假如 event.pageX = 1380px,那么右侧边栏应该移动:

\[moveStep = startWidth - event.pageX = 1255px - 1280px = -25px
\]

因此,右侧边栏由原来的 100px 增加 -25px 得到的新宽度是 75px。

添加监听器

只有当用户鼠标按下拖拽的控制器(rightResizeBar)时,才开启鼠标在 container 中移动的事件,事件函数为 moveRightBar。moveRightBar 计算右侧边栏的移动距离。

当用户在 container 范围内或在 rightResizeBar 元素内鼠标放下时,就移除 container 的事件:

// 1. 鼠标按下 rightResizeBar 元素,开启 container 的事件监听
rightResizeBar.addEventListener("mousedown", () => {
container.addEventListener("mousemove", moveRightBar);
}); // 2. 当鼠标从 rightResizeBar 放下时,取消监听
rightResizeBar.addEventListener("mouseup", () => {
container.removeEventListener("mousemove", moveRightBar);
}); // 3. 当鼠标从 container 范围内放下时,取消监听
container.addEventListener("mouseup", () => {
container.removeEventListener("mousemove", moveRightBar);
});

拖拽左侧边栏

左侧边栏的拖拽代码就非常简单了。鼠标不管从哪个方向移动,都是以浏览器左上角的原点为起点计算的鼠标 x、y 坐标值。而左侧边栏的左拖拽和右拖拽正好处于浏览器的左边部分,鼠标往左或往右拖拽多少 px,侧边栏的宽度就是event.pageX - container.offsetLeft

function moveLeftBar(event) {
setTimeout(() => {
let shiftWidth = event.pageX - container.offsetLeft;
left.style.width = shiftWidth + "px";
leftResizeBar.style.left = shiftWidth + "px";
}, 200);
}

添加监听器

leftResizeBar.addEventListener("mousedown", () => {
container.addEventListener("mousemove", moveLeftBar);
}); leftResizeBar.addEventListener("mouseup", () => {
container.removeEventListener("mousemove", moveLeftBar);
}); container.addEventListener("mouseup", () => {
container.removeEventListener("mousemove", moveLeftBar);
});

源码仓库

05#Web 实战:可拖拽的侧边栏的更多相关文章

  1. 纯JS Web在线可拖拽的流程设计器

    F2工作流引擎之-纯JS Web在线可拖拽的流程设计器 Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回. ...

  2. 基于JS的WEB会议室预订拖拽式图形界面的实现

    06年的一篇blog,转到这个博客上: 很早之前写的,后来由于这个功能模块取消,最终没有上线,所以与Server交互的那部分还没有写,不过那部分方案我也已经出来了,而且现在客户端这一部分已经通过了比较 ...

  3. F2工作流引擎之-纯JS Web在线可拖拽的流程设计器(八)

          Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回.传阅.转交,都可以非常方便快捷地实现,管理员 ...

  4. dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.

    http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...

  5. 07#Web 实战:实现 GitHub 个人主页项目拖拽排序

    实现效果图 GitHub 和 Gitee 个人主页中可以对自己的项目进行拖拽排序,于是我就想自己实现一个.本随笔只是记录一下大概的实现思路,如果感兴趣的小伙伴可以通过代码和本随笔的说明去理解实现过程. ...

  6. HT for Web列表和3D拓扑组件的拖拽应用

    很多可视化编辑器都或多或少有一些拖拽功能,比如从一个List列表中拖拽一个节点到拓扑组件上进行建模,并且在拖拽的过程中鼠标位置下会附带一个被拖拽节点的缩略图,那么今天我们就来实现这样的拖拽效果. 首先 ...

  7. HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)

    可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...

  8. HTML5 02. 多媒体控件、拖拽事件、历史记录、web存储、应用程序缓存、地理定位、网络状态

    多媒体 video:是行内块(text-align: center; 对行内块适用) <figure></figure>: 多媒体标签 : <figcaption> ...

  9. 从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  10. HTML5实战与剖析之原生拖拽(一拖拽历史概述)

    提起拖拽,我就想起了在JavaScript培训的时候一个非常好玩的效果,那就是拖拽了.可以用鼠标任意拖拽着一个物体到任何你想去的地方. 最早拥有JavaScript拖拽功能的是IE4浏览器.当时,网页 ...

随机推荐

  1. 5V升压12.6V

    产品概述 PW4053 是一款 5V 输入,最大 1.2A 充电电流,支持三节锂离子电池的升压充电管理 IC.PW4053 集成功率 MOS,采用异步开关架构,使其在应用时仅需极少的外围器件,可有效减 ...

  2. 01-复杂度2 Maximum Subsequence Sum (25分)

    Sample Input: 10 -10 1 2 3 4 -5 -23 3 7 -21 Sample Output: 10 1 4 题目有一个测试点是"最大和前面有一段是0",所以 ...

  3. 预编译SQL为什么能够防止SQL注入

    前言 之前我一个搞网络安全的朋友问了我一个的问题,为啥用 PreparedStatement 预编译的 SQL 就不会有被 SQL 注入的风险? 第一时间我联想到的是八股文中关于 Mybatis 的脚 ...

  4. 浅谈字节码增强技术系列2-Asm与Cglib

    作者:董子龙 前言 记得那是2022年秋天的第一场雨,比2021年来的稍晚一些,在那个秋雨朦胧的下午,正在工位上奋笔疾书的我突然听到了前面波哥对着手机听筒说出来的"温柔"的话语:说 ...

  5. PyTorch复现VGG学习笔记

    PyTorch复现ResNet学习笔记 一篇简单的学习笔记,实现五类花分类,这里只介绍复现的一些细节 如果想了解更多有关网络的细节,请去看论文<VERY DEEP CONVOLUTIONAL N ...

  6. 电脑无法自动获取ip地址

    1.按下win+r,输入cmd,打开命令提示符;2.执行ipconfig命令看下能否获取到ip地址:3.若不能,执行ipconfig /renew命令重新获取ip:4.执行ipconfig命令看下能否 ...

  7. 如何取消磁盘的BitLocker加密

    步骤1:打开开始[win]菜单,点击齿轮图标,打开[设置] 步骤2:在Windows设置视窗中点击[更新和安全] 步骤3:点击左侧[设备加密],点击视窗右侧[关闭] 步骤4:将提示是否需要关闭设备加密 ...

  8. JavaScript:操作符:逻辑运算符及其隐式转换数据类型

    逻辑非! 用来对布尔值进行取反,即!true = false: 当取反的变量不是布尔值,会进行隐式转换为布尔值: 非0的数字,都转换为true 非空字符串,转换为true 非空对象,转换为true I ...

  9. 用Echarts实现SpreadJS引用从属关系可视化

    在金融行业,我们经常会有审计审查的需求,对某个计算结果进行审查,但是这个计算结果可能依赖多个单元格,而且会有会有多级依赖的情况,如果让我们的从业人员靠眼睛找,工作量巨大,而且准确性存疑,基本上死路一条 ...

  10. 6、SQL模糊查询LIKE concat用法

    concat用来拼接查询的字符串: SELECT * FROM `page_demo` WHERE name LIKE concat('%',#{name},'%') 模糊查询: 1.%代表零个或多个 ...