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>
相关推荐
昨天;明天。今天。1 小时前
案例-表白墙简单实现
前端·javascript·css
数云界1 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd1 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常1 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer1 小时前
Vite:为什么选 Vite
前端
小御姐@stella1 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing2 小时前
【React】增量传输与渲染
前端·javascript·面试
eHackyd2 小时前
前端知识汇总(持续更新)
前端
万叶学编程5 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js