效果演示图

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

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. java中方法传参形式

    成员方法传参形式: 1.基本数据类型:传递的是值 public class Object03 { public static void main(String[] args) { AA aa = ne ...

  2. 8000字详解Thread Pool Executor

    摘要:Java是如何实现和管理线程池的? 本文分享自华为云社区<JUC线程池: ThreadPoolExecutor详解>,作者:龙哥手记 . 带着大厂的面试问题去理解 提示 请带着这些问 ...

  3. 浅聊一下Django如何避免xss攻击

    一.什么是xss攻击 xss攻击:----->web注入 xss跨站脚本攻击(Cross site script,简称xss)是一种"HTML注入",由于攻击的脚本多数时候是 ...

  4. CVE-2020-1938与CVE-2020-13935漏洞复现

    前言 最近在腾讯云上买了个服务器,准备用来学习.在安装了7.0.76的tomcat后,腾讯云提醒我存在两个漏洞,分别是CVE-2020-1938和CVE-2020-13935,在修复完漏洞后,准备复现 ...

  5. 温故知新 - 靶机练习-Toppo

    今天闲来无事,重新做了一下以前做过的第一个靶机(https://www.cnblogs.com/sallyzhang/p/12792042.html),这个靶机主要是练习sudo提权,当时不会也没理解 ...

  6. CentOS7升级Linux内核

    CentOS7升级Linux内核 什么是Linux内核 虽然时候使用 Linux 来表示整个操作系统,严格地说,Linux 只是个内核,而发行版的操作系统是一个完整功能的系统,它建立在内核之上,具有各 ...

  7. 10分钟做好 Bootstrap Blazor 的表格组件导出 Excel/Word/Html/Pdf

    上篇: Bootstrap Blazor 实战 通用导入导出服务(Table组件) 1.新建工程 新建工程b14table dotnet new blazorserver -o b14table 将项 ...

  8. 微信小程序转发onShareAppMessage设置path参数后在onload获取不到值的原因和解决方法

    官方实例:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Obje ...

  9. test20230109考试总结-2023寒搜索专题

    前言 2023 年的第一篇考试总结-- 赛时得分情况: A B C D E F G \(\texttt{Total}\) \(\texttt{Rank}\) \(40\) \(80\) \(0\) \ ...

  10. Java基础学习笔记-流程控制

    Java程序结构 顺序结构 分支选择结构 循环结构 顺序结构 分支选择结构 if-else Switch case Switch case 注意点 要配合break,要不就会一直往下走 case 值必 ...