欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

原生js实现React拖拽效果(resize)附带完整的demo

程序员文章站 2022-07-03 14:12:23
...

想找一个可以resize块的组件,找了好几天都没找到合适的。

尝试过的开源组件:
“react-rnd”:被拖拽的块采用的布局方式是“position:absolute”,更改布局的话拖拽的事件会失效,没有仔细去研究原理。但是我是在不知道这个布局怎么去比较好的兼容页面的flex布局,所以放弃了这个组件

网上查到的大多数拖拽组件是Draggable拖拽,多用于块的拖拽排序等,而我需要的是resize块的大小,两者截然不同。

看了有人用原生js写的html文件,上面的效果还是不错的,所以读懂了代码,在此代码的结构上进行了改动,运用到了react中。

核心代码:

var theobject = null;
var dir;
    //拖拽的时候初始化了一个object
  resizeObject = () => {
    this.el = null; //pointer to the object
    this.dir = "";      //type of current resize (n, s, e, w, ne, nw, se, sw)
    this.grabx = null;     //Some useful values
    this.graby = null;
    this.width = null;
    this.height = null;
    this.left = null;
    this.top = null;
  };
    //获取鼠标点击的X坐标
  getPositionX = (e) => {
    return e.clientX;
  };
  //获取鼠标点击的Y坐标
  getPositionY = (e) => {
    return e.clientY;
  };
    //获取拖拽的方向,从而确定鼠标的状态
  getDirection = (el, e) => {
    var xPos, yPos, offset, dir;
    dir = "";
    xPos = this.getPositionX(e);
    yPos = this.getPositionY(e);
    offset = 80; //The distance from the edge in pixels
    if (yPos < offset) dir += "n";
    else if (yPos > el.offsetHeight - offset) dir += "s";
    if (xPos < offset) dir += "w";
    else if (xPos > el.offsetWidth - offset) dir += "e";
    return dir;
  };
    //鼠标按下触发函数
  doDown = (e) => {
    var el = this.leftDiv;

    if (el == null) {
      theobject = null;
      return;
    }
    dir = this.getDirection(el, e);
    if (dir == "") return;

    theobject = new this.resizeObject();

    theobject.el = el;
    theobject.dir = dir;

    theobject.grabx = e.clientX;
    theobject.graby = e.clientY;
    theobject.width = el.offsetWidth;
    theobject.height = el.offsetHeight;
    theobject.left = el.offsetLeft;
    theobject.top = el.offsetTop;
    e.returnValue = false;
    e.cancelBubble = true;
  };
    //鼠标抬起触发函数
  doUp = () => {
    if (theobject != null) {
      theobject = null;
    }
  };
    //鼠标移动触发函数
  doMove = (e) => {
    var el, str, xMin, yMin;
    xMin = 8; //The smallest width possible
    yMin = 8; //             height
    el = this.leftDiv;
    if (el.className == "resizeMe") {
      str = this.getDirection(el, e);
      if (str == "") str = "default";
      else str += "-resize";
      el.style.cursor = str;
    }
    if (theobject != null) {
      if (dir.indexOf("e") != -1) {
        theobject.el.style.width = Math.max(xMin, theobject.width + e.clientX - theobject.grabx) + "px";
      }
      if (dir.indexOf("s") != -1){
        theobject.el.style.height = Math.max(yMin, theobject.height + e.clientY - theobject.graby) + "px";
      }
      if (dir.indexOf("w") != -1) {
        theobject.el.style.left = Math.min(theobject.left + e.clientX - theobject.grabx, theobject.left + theobject.width - xMin) + "px";
        theobject.el.style.width = Math.max(xMin, theobject.width - e.clientX + theobject.grabx) + "px";
      }
      if (dir.indexOf("n") != -1) {
        theobject.el.style.top = Math.min(theobject.top + e.clientY - theobject.graby, theobject.top + theobject.height - yMin) + "px";
        theobject.el.style.height = Math.max(yMin, theobject.height - e.clientY + theobject.graby) + "px";
      }
    }
    e.returnValue = false;
    e.cancelBubble = true;
  }

效果:
原生js实现React拖拽效果(resize)附带完整的demo

完整的demo地址点击获取