vue拖动改变两侧宽度

最近遇到了一个需求,就是需要实现拖动中间划线拖拽来实现两侧宽度改变。

参考了博主的文章 - vuejs中拖动改变元素宽度实现宽度自适应大小 - 可可西里的骄傲 - 博客园 (cnblogs.com)

结果呢,转而去研究了offset类的知识 - 一文搞懂offset系列、client系列、scroll系列 - 掘金 (juejin.cn)

感觉适合于我特别不扎实的前端小白来讲,用www.runoob.com/ 来学习一些前端原理与知识是再好不过的啦!!!

感觉学习就是永不止境...追剧可以剧荒,但是学习永远都有下一场,不怕学慌!最近在追 夏目友人帐,一下子看了整整六季,听说今年有第七季。最近就是剧荒阶段,就用学习来弥补吧....

话说,弥补得了吗????

不管了,先学着看看 ...(口吐芬芳)若有错误,希望能帮我在评论区纠正一下哈,谢谢大家。

知识1 - ClientX

csharp 复制代码
//clientX 事件属性返回当事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平坐标。
//客户区指的是当前窗口。
event.clientX

知识2 - offset系列与client系列

复制代码
offsetLeft - 元素边框外左边的水平距离(不包含边框)
offsetWidth - 元素宽度(包含边框)
clientWidth - 元素宽度(不包含边框)

知识3 - html dom事件对象之鼠标事件 - HTML DOM 事件对象 | 菜鸟教程 (runoob.com)

复制代码
onmousedown - 鼠标按钮被按下事件
onmousemove - 鼠标被移动事件
onmouseup - 鼠标按键被松开事件

知识3 - html dom事件对象之鼠标事件

vuejs中拖动改变元素宽度实现宽度自适应大小 - 可可西里的骄傲 - 博客园 (cnblogs.com)博主写的主要代码(我认为)分析了一下。

-- 主要分析左边拖拽条哈。

ini 复制代码
      var resize = document.getElementsByClassName('resize');//左边拖拽条
      var resize2 = document.getElementsByClassName('resize2');//右边拖拽条
      var left = document.getElementsByClassName('left');//获得left div元素
      var right = document.getElementsByClassName('right');//获得right div元素
      var mid = document.getElementsByClassName('mid');//获得mid div元素
      var box = document.getElementsByClassName('box');//获得box元素(left+resize+mid+right+resize2)
      
      //1.当鼠标按下时:(1)先获取当前鼠标的水平x--startx
        resize[0].onmousedown = function (e) {
          var startX = e.clientX;
          resize[0].left = resize[0].offsetLeft;
          
          //2.当鼠标按下后移动时:(2)再获取拖拽之后鼠标的水平x--endx
          document.onmousemove = function (e) {
            var endX = e.clientX;
            var rightW = right[0].offsetWidth;
            
            (3)moveLen为最终left元素的宽度,其中(endX - startX)表示鼠标拖拽的长度,若为正数,则往右拖拽;若为负数,则往左拖拽。
            var moveLen = resize[0].left + (endX - startX);
            var maxT = box[0].clientWidth - resize[0].offsetWidth;
            
            特别说明:movelen(left元素宽度)若小于150,表示拖拽向左过度,则让left元素==150,目的是为了不让left元素拖拽过度而消失;若大于原本left元素宽度+mid元素(最小设置为150)的话,表示向右拖拽过度,都覆盖掉第二个拖拽条resize2了,则需要讲拖拽条resize停在距离resize2拖拽条+150px的地方。
            if (moveLen < 150) moveLen = 150; 
            if (moveLen > maxT - rightW - 150) moveLen = maxT - rightW - 150;
            
            (4)设置左边元素长度为movelen,resize拖拽条位置为movelen,mid元素为整个box-right元素宽度-两个拖拽条宽度(10px)-movelen(当前left元素宽度)。
            resize[0].style.left = moveLen;
              left[0].style.width = moveLen + 'px';
              mid[0].style.width = (box[0].clientWidth - moveLen - rightW - 10) + 'px';
          }
          //3.当鼠标松开时:
          document.onmouseup = function (evt) {
            document.onmousemove = null;
            document.onmouseup = null; 
            resize[0].releaseCapture && resize[0].releaseCapture();//当鼠标进行松开操作时,触发 释放鼠标捕获。
          }
          
          resize[0].setCapture && resize[0].setCapture();//当鼠标进行按下操作,进行鼠标捕获。
          return false; //用来阻止onmousedown进行向父级元素进行冒泡操作
        }

右边也一样。

遇到的问题

作为前端小白的我,总会遇到一些奇葩的问题,比如:

(1)

ini 复制代码
var resize = document.getElementsByClassName('resize');

document.getElementsByClassName('resize')返回的是一个类数组对象,包含了所有具有指定类名('resize')的元素。

我遇到的问题就是resize.onmousedown,一直鼠标猛点都点不动,排查了原因原来是这样子改: resize[0].onmousedown,我完全忽略了一个网页中,叫resize的元素可以有很多个。

(2)

setCapture与releaseCapture这两兄弟已经被弃用了,建议改为:

scss 复制代码
resize[0].releasePointerCapture && resize[0].releasePointerCapture(1); 
resize[0].setPointerCapture && resize[0].setPointerCapture(1); 

(3)

元素.clientx到底原理如何?

就是在整个你看得到的整个屏幕上,与左屏幕边缘到鼠标的距离。 所以,若box嵌套在屏幕中规定的某个子div中,记得要剪掉左div(其他元素)的宽度。 总得一句话,要保证与box左边缘的距离,而不是与屏幕左边缘的距离,后者可能会导致后期移动有误吧。

我的代码

源代码-vue中实现拖动调整左右两侧div的宽度 - 掘金 (juejin.cn)

我修改了一丢丢而已。

xml 复制代码
<template>
	<div>
		<el-row type="flex" class="row-bg" justify="space-between">
			<el-col :span="3" class="col01">
				a
			</el-col>
			<el-col :span="20">
				<div class="box" ref="box">
					<div class="left">
						<!--左侧div内容-->11111
					</div>
					<div class="resize" title="收缩侧边栏">
						⋮
					</div>
					<div class="mid">
						<!--右侧div内容-->33333
					</div>
				</div>
			</el-col>
			<el-col :span="1">
				c
			</el-col>
		</el-row>
	</div>
</template>

<script>
	export default {
		data() {
			return {}
		},
		mounted() {
			this.dragControllerDiv();
		},
		methods: {
			dragControllerDiv: function() {
				var resize = document.getElementsByClassName('resize');
				var left = document.getElementsByClassName('left');
				var mid = document.getElementsByClassName('mid');
				var box = document.getElementsByClassName('box');
				var col01=document.getElementsByClassName('col01');
				// 鼠标按下事件
				resize[0].onmousedown = function(e) {
					//颜色改变提醒
					resize[0].style.background = '#818181';
					var startX = e.clientX-col01[0].offsetWidth;
					resize[0].left = resize[0].offsetLeft;
					// 鼠标拖动事件
					document.onmousemove = function(e) {
						var endX = e.clientX-col01[0].offsetWidth;
						var moveLen = resize[0].left + (endX -startX)-col01[0].offsetWidth; 
						var maxT = box[0].clientWidth - resize[0].offsetWidth; 

						if (moveLen < 32) moveLen = 32; 
						if (moveLen > maxT - 150) moveLen = maxT - 150; 

						resize[0].style.left = moveLen; 

						left[0].style.width = moveLen + 'px';
						mid[0].style.width = (box[0].clientWidth - moveLen - 10) + 'px';
					};
					// 鼠标松开事件
					document.onmouseup = function(evt) {
						//颜色恢复
						resize[0].style.background = '#d6d6d6';
						document.onmousemove = null;
						document.onmouseup = null;
						resize[0].releasePointerCapture && resize[0].releasePointerCapture(1); 
						
					};
					resize[0].setPointerCapture && resize[0].setPointerCapture(1); 
					return false;
				};
			},
		}
	}
</script>

<style scoped>
	.el-col {
		margin: 3px;
	}

	/* 拖拽相关样式 */
	/*包围div样式*/
	.box {
		width: 100%;
		height: 100%;
		overflow: hidden;
	}

	.mid {
		width: calc(32% - 10px);
		height: 100%;
		background: #FFFFFF;
		float: left;
	}

	/*拖拽区div样式*/
	.resize {
		cursor: col-resize;
		float: left;
		position: relative;
		top: 45%;
		background-color: #d6d6d6;
		border-radius: 5px;
		margin-top: -10px;
		width: 10px;
		height: 50px;
		background-size: cover;
		background-position: center;
		/*z-index: 99999;*/
		font-size: 32px;
		color: white;
	}

	/*拖拽区鼠标悬停样式*/
	.resize:hover {
		color: #444444;
	}
	.left {
		float: left;
		width: 68%;
		/*右侧初始化宽度*/
		height: 100%;
		background: #fff;
	}
</style>
相关推荐
咖啡の猫2 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲4 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5815 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路5 小时前
GeoTools 读取影像元数据
前端
ssshooter5 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry6 小时前
Jetpack Compose 中的状态
前端
dae bal7 小时前
关于RSA和AES加密
前端·vue.js
柳杉7 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog7 小时前
低端设备加载webp ANR
前端·算法
LKAI.7 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi