首页 > 代码库 > javascript动画系列第四篇——拖拽改变元素大小

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>

<iframe style="width: 100%; height: 130px;" src="http://sandbox.runjs.cn/show/tqf1akhu" frameborder="0" width="320" height="240"></iframe>

大小改变

  处于左侧范围时,改变元素的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>

<iframe style="width: 100%; height: 200px;" src="http://sandbox.runjs.cn/show/g5zhv4rd" frameborder="0" width="320" height="240"></iframe>

代码优化

  与拖拽移动元素一样,拖拽改变元素大小也存在同样的问题

  问题一:文字及图片具有原生的拖放行为,通过取消默认行为可解决。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>

<iframe style="width: 100%; height: 200px;" src="http://sandbox.runjs.cn/show/pf6xdtq4" frameborder="0" width="320" height="240"></iframe>

源码查看

<script type="text/javascript">// 0){ return; } if(select[i].getBoundingClientRect().top <= 0 && select[i+1]){ if(select[i+1].getBoundingClientRect().top > 0){ change(oCon.children[i+2]) } }else{ change(oCon.children[select.length+1]) } }}document.body.onmousewheel = wheel;document.body.addEventListener(‘DOMMouseScroll‘,wheel,false);var oCon = document.getElementById("content");var close = oCon.getElementsByTagName(‘span‘)[0];close.onclick = function(){ if(this.innerHTML == ‘显示目录‘){ this.innerHTML = ‘ב; this.style.background = ‘‘; oCon.style.border = ‘2px solid #ccc‘; oCon.style.width = ‘‘; oCon.style.height = ‘‘; oCon.style.overflow = ‘‘; oCon.style.lineHeight = ‘30px‘; }else{ this.innerHTML = ‘显示目录‘; this.style.background = ‘#3399ff‘; oCon.style.border = ‘none‘; oCon.style.width = ‘60px‘; oCon.style.height = ‘30px‘; oCon.style.overflow = ‘hidden‘; oCon.style.lineHeight = ‘‘; }}for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].onmouseover = function(){ this.style.color = ‘#3399ff‘; } oCon.children[i].onmouseout = function(){ this.style.color = ‘inherit‘; if(this.mark){ this.style.color = ‘#3399ff‘; } } oCon.children[i].onclick = function(){ change(this); } }function change(_this){ for(var i = 2; i < oCon.children.length; i++){ oCon.children[i].mark = false; oCon.children[i].style.color = ‘inherit‘; oCon.children[i].style.textDecoration = ‘none‘; oCon.children[i].style.borderColor = ‘transparent‘; } _this.mark = true; _this.style.color = ‘#3399ff‘; _this.style.textDecoration = ‘underline‘; _this.style.borderColor = ‘#2175bc‘; }// ]]></script><script type="text/javascript" src="http://files.cnblogs.com/files/xiaohuochai/contextMenu.js"></script>

javascript动画系列第四篇——拖拽改变元素大小