一、实现效果

封装了三个methods方法,传入对应节点即可实现对应元素节点的拉伸收缩。

二、代码

1. 函数封装
/***
* 让指定的dom元素支持沿x轴的拉伸收缩
* oBox为指定的dom节点
* e为鼠标按键默认传入的对象
*/
 moveX(oBox, e) {
      let x = e.clientX;
      let oBoxW = oBox.offsetWidth;
      document.onmousemove = e => (oBox.style.width = oBoxW + e.clientX - x + 'px')
      document.onmouseup = () => [document.onmousemove, document.onmouseup] = [null, null]
      e.preventDefault && e.preventDefault()
    },
moveY(oBox, e) {
      if (e.path.some(v => v.getAttribute && v.getAttribute('class') && v.getAttribute('class').includes('lineBlock'))
        || e.path.some(v => v.getAttribute && v.getAttribute('class') && v.getAttribute('class').includes('blockItem'))) {
        return
      }
      let y = e.clientY;
      let oBoxH = oBox.offsetHeight;
      document.onmousemove = e => oBox.style.height = oBoxH + e.clientY - y + 'px'
      document.onmouseup = () => [document.onmousemove, document.onmouseup] = [null, null]
      e.preventDefault && e.preventDefault()
    },
moveXY(oBox, e) {
      let x = e.clientX;
      let y = e.clientY;
      let oBoxH = oBox.offsetHeight;
      let oBoxW = oBox.offsetWidth;
      document.onmousemove = e => {
        let xx = e.clientX
        let yy = e.clientY
        oBox.style.width = oBoxW + xx - x + 'px'
        oBox.style.height = oBoxH + yy - y + 'px'
        return false;
      }
      document.onmouseup = () => [document.onmousemove, document.onmouseup] = [null, null]
      e.preventDefault && e.preventDefault()
    },
2. 函数调用

定义了一个包含所有要添加横向拉伸事件的数组,遍历这个数组将这些节点的onmousedown事件设定为moveX函数。

let dragX = [];
dragX.push(...document.getElementsByClassName('blockItem'), ...document.getElementsByClassName('lineBlock'));

dragX.map(v => (v.onmousedown事件设定为 = this.moveX.bind({}, v)));
3.dom节点

设定一个blockItemlineBlock的div就尝试拖拽了。

三、坑点介绍

1. 将需要拖拽的元素传入而不是使用e.target获取

一开始觉得一个参数就能搞定,但实际开发中发现e.target指向的不一定是这个元素本身,也有可能是它的某个子元素,这样就变成了对其子元素的拉伸实现。

2.父级元素支持拉伸导致给子元素添加的拉伸功能失效

在给父元素添加拉伸事件时判断是否当前鼠标按下对应元素是需要支持支持拉伸事件的子元素。(示例代码如下)

if (e.path.some(v => v.getAttribute && v.getAttribute('class') && v.getAttribute('class').includes('lineBlock'))
|| e.path.some(v => v.getAttribute && v.getAttribute('class') && v.getAttribute('class').includes('blockItem'))) {
return
}

聪明的小伙伴应该发现了,以上代码虽然是在vue项目中实现的,但实际用到的语法主要还是原生js。也就是说,要想在原生js中实现呢元素拉伸功能根据以上思路也是非常方便。

END

Logo

前往低代码交流专区

更多推荐