javascript动画系列第四篇——拖拽改变元素大小
×
目录
[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;
//处于左侧范围
if(areaL){
thatL= e.clientX - disL + 'px';
thatW= EW + EX - e.clientX + 'px';
}
//处于右侧范围
if(areaR){thatW= EW + e.clientX - EX + 'px';}
//处于上侧范围
if(areaT){
thatT = e.clientY - disH + 'px';
thatH = EH + EY - e.clientY + 'px';
}
//处于下侧范围
if(areaB){thatH = EH + e.clientY - EY + 'px';}
//范围限定
if(parseInt(thatW) < 60){thatW = '60px';}
if(parseInt(thatH) < 60){thatH = '60px';}
//赋值
if(thatW != undefined){that.style.width = thatW;}
if(thatH != undefined){that.style.height = thatH;}
if(thatT != undefined){that.style.top = thatT;}
if(thatL != undefined){that.style.left = thatL;}
}
document.onmouseup = function(e){
//关闭改变元素尺寸功能
document.onmousemove = null;
//释放全局捕获
if(that.releaseCapture){
that.releaseCapture();
}
}
}
}
</script> 源码查看
相关推荐
zrtlin 2020-11-09
wikiwater 2020-10-27
heheeheh 2020-10-19
Crazyshark 2020-09-15
ZGCdemo 2020-08-16
jczwilliam 2020-08-16
littleFatty 2020-08-16
idning 2020-08-03
jinxiutong 2020-07-26
lanzhusiyu 2020-07-19
Skyline 2020-07-04
xiaofanguan 2020-06-25
Aveiox 2020-06-23
dragonzht 2020-06-17