[1]原理簡介 [2]範圍圈定 [3]大小改變 [4]代碼優化 ...
×
目錄
[1]原理簡介 [2]範圍圈定 [3]大小改變[4]代碼優化前面的話
拖拽可以讓元素移動,也可以改變元素大小。本文將詳細介紹拖拽改變元素大小的效果實現
原理簡介
拖拽讓元素移動,是改變定位元素的left和top值實現的。而拖拽改變元素大小,則還需要改變元素的寬高
範圍圈定
我們把改變元素大小的範圍圈定在距離相應邊10px的範圍內
左側邊界L = obj.offsetLeft + 10
右側邊界R = obj.offsetLeft + obj.offsetWidth - 10
上側邊界T = obj.offsetTop + 10
下側邊界B = obj.offsetTop + obj.offsetHeight - 10
<div id="test" style="height: 100px;width: 100px;background-color: pink;">測試文字</div> <script> test.onmousemove = function(e){ e = e || event; //元素邊界確定 var L0 = this.offsetLeft; var R0 = this.offsetLeft + this.offsetWidth; var T0 = this.offsetTop; var B0 = this.offsetTop + this.offsetHeight; //範圍邊界確定 var L = L0 + 10; var R = R0 - 10; var T = T0 + 10; var B = B0 - 10; //範圍確定 var areaL = e.clientX < L; var areaR = e.clientX > R; var areaT = e.clientY < T; var areaB = e.clientY > B; //左側範圍 if(areaL){ this.style.cursor = 'w-resize'; } //右側範圍 if(areaR){ this.style.cursor = 'e-resize'; } //上側範圍 if(areaT){ this.style.cursor = 'n-resize'; } //下側範圍 if(areaB){ this.style.cursor = 's-resize'; } //左上範圍 if(areaL && areaT){ this.style.cursor = 'nw-resize'; } //右上範圍 if(areaR && areaT){ this.style.cursor = 'ne-resize'; } //左下範圍 if(areaL && areaB){ this.style.cursor = 'sw-resize'; } //右下範圍 if(areaR && areaB){ this.style.cursor = 'se-resize'; } //中間範圍 if(!areaL && !areaR && !areaT && !areaB){ this.style.cursor = 'default'; } } </script>
大小改變
處於左側範圍時,改變元素的left和width值
處於右側範圍時,改變元素的left值
處於上側範圍時,改變元素的top和height值
處於下側範圍時,改變元素的height值
[註意]元素改變前的狀態是指按下滑鼠的瞬時元素的狀態
<div id="test" style="height: 100px;width: 100px;background-color: pink;position:absolute;top:100px;left:200px;">測試文字</div> <script> //共用mousedown事件的變數,設置為全局變數 var EW,EH,EX,EY,disL,disH; test.onmousemove = function(e){ e = e || event; //元素邊界確定 var L0 = this.offsetLeft; var R0 = this.offsetLeft + this.offsetWidth; var T0 = this.offsetTop; var B0 = this.offsetTop + this.offsetHeight; //範圍邊界確定 var L = L0 + 10; var R = R0 - 10; var T = T0 + 10; var B = B0 - 10; //範圍確定 var areaL = e.clientX < L; var areaR = e.clientX > R; var areaT = e.clientY < T; var areaB = e.clientY > B; //左側範圍 if(areaL){this.style.cursor = 'w-resize';} //右側範圍 if(areaR){this.style.cursor = 'e-resize';} //上側範圍 if(areaT){this.style.cursor = 'n-resize';} //下側範圍 if(areaB){this.style.cursor = 's-resize';} //左上範圍 if(areaL && areaT){this.style.cursor = 'nw-resize';} //右上範圍 if(areaR && areaT){this.style.cursor = 'ne-resize';} //左下範圍 if(areaL && areaB){this.style.cursor = 'sw-resize';} //右下範圍 if(areaR && areaB){this.style.cursor = 'se-resize';} //中間範圍 if(!areaL && !areaR && !areaT && !areaB){this.style.cursor = 'default';} //如果改變元素尺寸功能開啟 if(test.clientChange){ //處於左側範圍 if(areaL){ this.style.left = e.clientX - disL + 'px'; this.style.width = EW + EX - e.clientX + 'px'; } //處於右側範圍 if(areaR){this.style.width = EW + e.clientX - EX + 'px';} //處於上側範圍 if(areaT){ this.style.top = e.clientY - disH + 'px'; this.style.height = EH + EY - e.clientY + 'px'; } //處於下側範圍 if(areaB){this.style.height = EH + e.clientY - EY + 'px'; } } test.onmousedown = function(e){ e = e || event; //記錄滑鼠按下時的寬高及滑鼠clienX、clientY值 EW = this.offsetWidth; EH = this.offsetHeight; EX = e.clientX; EY = e.clientY; //記錄滑鼠按下位置距離元素左側的距離 disL = EX - L0; //記錄滑鼠按下位置距離元素上側的距離 disH = EY - T0; //開啟改變元素尺寸功能 test.clientChange = true; } test.onmouseup = function(e){ //關閉改變元素尺寸功能 test.clientChange = false; } } </script>
代碼優化
與拖拽移動元素一樣,拖拽改變元素大小也存在同樣的問題
問題一:文字及圖片具有原生的拖放行為,通過取消預設行為可解決。IE8-瀏覽器不支持,使用全局捕獲來實現IE相容
問題二:拖放過快,滑鼠移動速度快於mousemove觸發速度時,滑鼠脫離元素,使後續事件無法發生。把mousemove事件加在document上,即可解決
問題三:元素大小改變需要有範圍限制
<div id="test" style="height: 100px;width: 100px;background-color: pink;position:absolute;top:100px;left:200px;">測試文字</div> <script> test.onmousemove = function(e){ e = e || event; //元素邊界確定 var L0 = this.offsetLeft; var R0 = this.offsetLeft + this.offsetWidth; var T0 = this.offsetTop; var B0 = this.offsetTop + this.offsetHeight; //範圍邊界確定 var L = L0 + 10; var R = R0 - 10; var T = T0 + 10; var B = B0 - 10; //範圍確定 var areaL = e.clientX < L; var areaR = e.clientX > R; var areaT = e.clientY < T; var areaB = e.clientY > B; //左側範圍 if(areaL){this.style.cursor = 'w-resize';} //右側範圍 if(areaR){this.style.cursor = 'e-resize';} //上側範圍 if(areaT){this.style.cursor = 'n-resize';} //下側範圍 if(areaB){this.style.cursor = 's-resize';} //左上範圍 if(areaL && areaT){this.style.cursor = 'nw-resize';} //右上範圍 if(areaR && areaT){this.style.cursor = 'ne-resize';} //左下範圍 if(areaL && areaB){this.style.cursor = 'sw-resize';} //右下範圍 if(areaR && areaB){this.style.cursor = 'se-resize';} //中間範圍 if(!areaL && !areaR && !areaT && !areaB){this.style.cursor = 'default';} test.onmousedown = function(e){ var that = this; e = e || event; //取消預設行為 if(e.preventDefault){ e.preventDefault(); } //IE8-瀏覽器阻止預設行為 if(that.setCapture){ that.setCapture(); } //記錄滑鼠按下時的寬高及滑鼠clienX、clientY值 var EW = this.offsetWidth; var EH = this.offsetHeight; var EX = e.clientX; var EY = e.clientY; //記錄滑鼠按下位置距離元素左側的距離 var disL = EX - L0; //記錄滑鼠按下位置距離元素上側的距離 var disH = EY - T0; document.onmousemove = function(e){ var thatL,thatW,thatT,thatH; e = e || event;