效果演示图

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

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. 【SQL基础】【关键字大写】条件查询:比较、不等于、IN、为空、BETWEEN

    〇.概述 1.内容介绍 条件查询:比较.不等于.IN.为空.BETWEEN 2.建表语句 drop table if exists user_profile; CREATE TABLE `user_p ...

  2. node版本管理工具fnm踩坑

    我建议是直接不要用fnm,还是老老实实用nvm吧 fnm下下来电脑防火墙会报毒(用github上推荐的cargo install fnm方式下载,并非第三方安装) Trojan.Generic.HgE ...

  3. RocketMQ Connect 构建流式数据处理平台

    本文作者:孙晓健,Apache RocketMQ Committer 01 RocketMQ Connect RocketMQ Connect 是一款可扩展的在 RocketMQ 与其他系统之间做流式 ...

  4. 粘包、struct模块、进程并行与并发

    目录 粘包现象 struct模块 粘包代码实战 udp协议(了解) 并发编程理论 多道技术 进程理论 进程并行与并发 进程的三状态 粘包现象 1.服务端连续执行三次recv 2.客户端连续执行三次se ...

  5. CLI框架:klish安装与使用

    在通信设备领域,思科的路由器设备可以用CLI进行操作.这里介绍的开源项目klish是思科CLI风格(CISCO-like CLI)的框架.命令配置文件为xml格式. 源码:pkun/klish: Th ...

  6. apt install protobuf

    protobuf介绍:https://www.cnblogs.com/niuben/p/14212711.html protobuf利用源码编译安装已经看到过很多方法,这里总结下用apt安装的方法. ...

  7. HNCTF的pyjail做题过程详解

    简述: 因为本人对python的内置函数理解也不是深入,在做题过程中也是靠着出题人的hint和google大法才做出来几题,详细的解题过程和知识点讲解可以看一下春哥的知乎,[PyJail] pytho ...

  8. 【转载】SQL SERVER 存储过程中执行动态Sql语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  9. [数学理论] NP问题解释

    转载自http://m.blog.csdn.net/csshuke/article/details/74909562 希望通过这篇文章可以不仅让计算机相关专业的人可以看懂和区分什么是P类问题什么是NP ...

  10. Hadoop详解(02)Hadoop集群运行环境搭建

    Hadoop详解(02)Hadoop集群运行环境搭建 虚拟机环境准备 虚拟机节点数:3台 操作系统版本:CentOS-7.6-x86-1810 虚拟机 内存4G,硬盘99G IP地址分配 192.16 ...