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

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,那么右侧边栏应该移动:
\]
因此,右侧边栏由原来的 100px 增加 55px 得到的新宽度是 155px:
\]
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,那么右侧边栏应该移动:
\]
因此,右侧边栏由原来的 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 实战:可拖拽的侧边栏的更多相关文章
- 纯JS Web在线可拖拽的流程设计器
F2工作流引擎之-纯JS Web在线可拖拽的流程设计器 Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回. ...
- 基于JS的WEB会议室预订拖拽式图形界面的实现
06年的一篇blog,转到这个博客上: 很早之前写的,后来由于这个功能模块取消,最终没有上线,所以与Server交互的那部分还没有写,不过那部分方案我也已经出来了,而且现在客户端这一部分已经通过了比较 ...
- F2工作流引擎之-纯JS Web在线可拖拽的流程设计器(八)
Web纯JS流程设计器无需编程,完全是通过鼠标拖.拉.拽的方式来完成,支持串行.并行.分支.异或分支.M取N路分支.会签.聚合.多重聚合.退回.传阅.转交,都可以非常方便快捷地实现,管理员 ...
- dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.
http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...
- 07#Web 实战:实现 GitHub 个人主页项目拖拽排序
实现效果图 GitHub 和 Gitee 个人主页中可以对自己的项目进行拖拽排序,于是我就想自己实现一个.本随笔只是记录一下大概的实现思路,如果感兴趣的小伙伴可以通过代码和本随笔的说明去理解实现过程. ...
- HT for Web列表和3D拓扑组件的拖拽应用
很多可视化编辑器都或多或少有一些拖拽功能,比如从一个List列表中拖拽一个节点到拓扑组件上进行建模,并且在拖拽的过程中鼠标位置下会附带一个被拖拽节点的缩略图,那么今天我们就来实现这样的拖拽效果. 首先 ...
- HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)
可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...
- HTML5 02. 多媒体控件、拖拽事件、历史记录、web存储、应用程序缓存、地理定位、网络状态
多媒体 video:是行内块(text-align: center; 对行内块适用) <figure></figure>: 多媒体标签 : <figcaption> ...
- 从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- HTML5实战与剖析之原生拖拽(一拖拽历史概述)
提起拖拽,我就想起了在JavaScript培训的时候一个非常好玩的效果,那就是拖拽了.可以用鼠标任意拖拽着一个物体到任何你想去的地方. 最早拥有JavaScript拖拽功能的是IE4浏览器.当时,网页 ...
随机推荐
- 3A锂电池充电管理芯片PW4035
PW4052 是一颗适用于单节锂电池的.具有恒压/恒流充电模式的充电管理 IC.该芯片采用开关型的工作模式, 能够为单节锂电池提供快速. 高效且简单的充电管理解决方案. PW4052 采用三段式充电管 ...
- Jenkins基本配置
1.Configure System (系统设置) 在系统设置这里,只需要设置最后面的一项,配置远程服务器地址,即代码最终运行的服务器地址信息,当然这里是可以配置多台远程Linux服务器的,配置完成后 ...
- hashlib加密模块 subprocess模块 logging日志模块
目录 hashlib加密模块 简介 hashlib使用流程 hashilb加密模块使用说明 明文绑定密文 密文长度不变 多次传入 密文不可解密原因 加盐处理(salt) 普通加盐 动态加盐 加密实际运 ...
- 模板层之标签 自定义过滤器及标签 模板的继承与导入 模型层之前期准备 ORM常用关键字
目录 模板层之标签 if判断 for循环 自定义过滤器.标签及inclusion_tag(了解) 前期三步骤 自定义过滤器(最大只能接收两个参数) 自定义标签(参数没有限制) 自定义inclusion ...
- java中的自增运算
本文主要阐明java中的自增运算 1.当i ++ 与 ++ i作为单独语句时,作用与i = i +1一样 2.当赋值时,结果就不一样了 temp = i ++: 操作顺序:1)temp = i: 2) ...
- js修改数组中的属性名
将数组 [{id:"1",name:"AAA"}] 修改为 ===> [{id:"1",text:"AAA",va ...
- 工业数据分析为什么要用FusionInsight MRS IoTDB?
摘要:MRS IoTDB,它是华为FusionInsight MRS大数据套件中的时序数据库产品,在深度参与Apache IoTDB社区开源版的基础上推出的高性能企业级时序数据库产品. 本文分享自华为 ...
- Ubuntu 22.04 安装 utools 时的疑难杂症
Error: libcrypto.so.1.1 原因:libcrypto.so.1.1 该依赖的版本不对,ubuntu 默认是使用的 openssl3 的依赖 这个是 openssl1 的 wget ...
- 深入Typescript--03-Typescript中的类(努力加餐饭)
Typescript中的类 一.TS中定义类 class Pointer{ x!:number; // 实例上的属性必须先声明 y!:number; constructor(x:number,y?:n ...
- Blazor Hybrid (Blazor混合开发)更好的读取本地图片
在 Blazor Hybrid 应用中,Razor 组件在设备上本机运行. 组件通过本地互操作通道呈现到嵌入式 Web View 控件. 组件不在浏览器中运行,并且不涉及 WebAssembly. R ...