1. 程式人生 > >原生js實現React拖拽效果(resize)附帶完整的demo

原生js實現React拖拽效果(resize)附帶完整的demo

想找一個可以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; }

效果:
這裡寫圖片描述