上次做的簡單的拖拽:javascript簡單拖拽練習(鼠標事件 mousedown mousemove mouseup)
這次增加了一些相關的功能,增加四個角的拉伸改變寬度,主要還是用到一些簡單的坐標位置計算,沒有什么技術難度,熟練了一下自己對拖拽的運用
不曉得為什么粘貼到博客園上就不支持IE6了,直接在本地是支持IE6的,有個問題就是,鼠標點擊的時候光標會變為選擇文字的光標,不知道應該怎么
處理這個問題呢?
DEMO如下:
按此處拖動
中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間 內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容 中間內容中間內容中間內容中間內容中間內容中間內容
在此記錄一下代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>簡單拖拽擴展</title> <style type="text/css"> *{margin:0;padding:0;} #outwarp{ margin:20px auto; width:600px; height:600px; background:#fff; border:1px solid #333; position: relative; } .controlBox{ width:200px; height:200px; position: absolute; left:25px; top:50px; background:#ccc; font-size:12px; color:#fff; border: 1px solid #333;} .controlBar{cursor: move;} .controlBar h2{ font-size:12px; text-align: center; line-height: 25px; background: blue;} .innerCon{text-align: left; line-height: 20px;} .innerCon p{ padding: 10px; color: #000;} .resize{ position: absolute; height: 10px; width:10px; color: white; z-index: 10; background: red;} .lt{left:0;right:0; cursor:nw-resize;} .tr{right:0;top: 0;cursor:ne-resize;} .rb{right:0;bottom: 0; cursor:nw-resize;} .bl{left:0;bottom:0;cursor:ne-resize;} </style> </head> <body> <div id="outwarp"> <div class="controlBox"> <div class="resize lt"></div> <div class="resize tr"></div> <div class="resize rb"></div> <div class="resize bl"></div> <div class="controlBar"> <h2>按此處拖動</h2> </div> <div class="innerCon"> <p>中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間 內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容中間內容 中間內容中間內容中間內容中間內容中間內容中間內容</p> </div> </div> </div> <script type="text/javascript"> (function () { //定義便捷函數getElementById,getElementsByTagName,getElementsByClassName,bindFunction,bindEvent function $() { var elements = new Array(); for (var i = 0; i < arguments.length; i++) { var element = arguments[i]; if (typeof element == 'string') { element = document.getElementById(element); } if (!element) { continue; } if (arguments.length == 1) { return element; } elements.push(element); } return elements; } function $$(tag, parent) { parent = parent || document; return $(parent).getElementsByTagName(tag); } function $$$(str, parent, tag) { if (parent) { parent = $(parent); } else { parent = document; } tag = tag || '*'; var els = parent.getElementsByTagName(tag), arr = []; for (var i = 0, n = els.length; i < n; i++) { for (var j = 0, k = els[i].className.split(' '), l = k.length; j < l; j++) { if (k[j] == str) { arr.push(els[i]); break; } } } return arr; } function bindFunction(obj, func) { return function () { return func.apply(obj, arguments); }; } function bindEvent(element, type, func) { if (element.addEventListener) { element.addEventListener(type, func, false); //false 表示冒泡 } else if (element.attachEvent) { element.attachEvent('on' + type, func); } else { element['on' + type] = func; } } /*定義拖拽類*/ var DragBox = function (options) { var outWarpId = this.outWarpId = options.outWarpId;//獲取最外圍的包裹層ID var outWarp = $(outWarpId);//獲取外圍包裹層對象 var controlBox = this.controlBox = $$$('controlBox', outWarp, 'div')[0]; //被拖動的層 this.controlBar = $$$('controlBar', controlBox, 'div')[0]; this.resizeLt = $$$('lt', controlBox, 'div')[0]; this.resizeTr = $$$('tr', controlBox, 'div')[0]; this.resizeRb = $$$('rb', controlBox, 'div')[0]; this.resizeBl = $$$('bl', controlBox, 'div')[0]; /*獲取outWarpId信息*/ this.warpWidth = outWarp.offsetWidth - 2; // 對象寬度 this.warpHeight = outWarp.offsetHeight - 2; // 對象高度 this.warpLeft = outWarp.offsetLeft; //對象靠LEFT距離 this.warpTop = outWarp.offsetTop; //對象靠TOP距離 /*定義拖動的對象*/ this.draging = null; this.bind(); }; DragBox.prototype = { moveBox:function (event) { event = event || window.event; var target = event.target || event.srcElement; // 記錄滾動條位置 this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop; this.scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; //記錄光標的位置 var mousex = event.clientX; // 光標LEFT var mousey = event.clientY; //光標TOP console.log('mousex:' + mousex); console.log('mousey:' + mousey); // 光標相對outwarp層的坐標 var posx = mousex + this.scrollLeft - this.warpLeft; var posy = mousey + this.scrollTop - this.warpTop; // 多次用到this.controlBox 賦值一個短變量名 var my = this.controlBox; // 多次用到this.controlBox.style,賦值一個短變量名 var myStyle = my.style; // 最小尺寸 var minWidth = 200,minHeight = 200; switch(event.type){ case 'mousedown': /*記錄相關初始信息*/ if(target.parentNode.className.indexOf('controlBar')!=-1){ this.draging = this.controlBox; //賦值拖動對象 } if(target.className.indexOf('rb')!= -1){ this.draging = this.resizeRb; // 賦值為右下角拖動 } if(target.className.indexOf('tr')!= -1){ this.draging = this.resizeTr; // 賦值為右上角改變大小 } if(target.className.indexOf('lt')!= -1){ this.draging = this.resizeLt; // 賦值為左上角改變大小 } if(target.className.indexOf('bl') != -1){ this.draging = this.resizeBl; } //alert('this.scrollTop:'+this.scrollTop); //點擊時記錄拖動層的初始信息 this.controlBoxWidth = my.offsetWidth; //拖動層的寬度 this.controlBoxHeight = my.offsetHeight; //拖動層的寬度 this.controlBoxLeft = my.offsetLeft; //拖動層的LEFT坐標 this.controlBoxTop = my.offsetTop; //拖動層的TOP坐標 // 記錄鼠標按下時鼠標相對與拖動層的距離 this.mx = posx - this.controlBoxLeft; this.my = posy - this.controlBoxTop; // 記錄左下角的坐標,因為按住右上拖動的時候左下角不動 this.lb_x = my.offsetWidth + my.offsetLeft; this.lb_y = my.offsetHeight + my.offsetTop; console.log('my.offsetHeight:'+my.offsetHeight+'my.offsetTop:'+my.offsetTop); // 記錄右下角坐標,按住左上角拖動的時候右下角不動 this.rb_x = my.offsetLeft + my.offsetWidth; this.rb_y = my.offsetTop + my.offsetHeight; // 記錄右上角坐標,當按住左下角的時候右上角不動 this.lt_x = my.offsetLeft + my.offsetWidth; this.lt_y = my.offsetTop; break; case 'mousemove': if (this.draging == this.controlBox){ window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); //取消頁面上由於鼠標按下拖動造成的選中文字和圖片的選擇狀態 //拖動層的位置 var left = posx - this.mx; var top = posy - this.my; left < 0 && (left = 0); top < 0 && (top = 0); left > (this.warpWidth - this.controlBoxWidth) && (left = this.warpWidth - this.controlBoxWidth); top > (this.warpHeight - this.controlBoxHeight) && (top = this.warpHeight - this.controlBoxHeight); //改變位置 myStyle.left = left + 'px'; myStyle.top = top + 'px'; //右下角拖動 } else if (this.draging == this.resizeRb) { // 需要改變的寬度 var changeWidth = posx - this.controlBoxWidth - this.controlBoxLeft, changeHeight = posy - this.controlBoxHeight - this.controlBoxTop, // 計算總寬度 allWidth = this.controlBoxWidth + changeWidth + this.controlBoxLeft , allHeight = this.controlBoxHeight + changeHeight + this.controlBoxTop; //改變寬度 myStyle.width = (this.controlBoxWidth + changeWidth) + 'px'; myStyle.height = (this.controlBoxHeight + changeHeight) + 'px'; // 限制最大寬度 if (allWidth > this.warpWidth) { myStyle.width = ( this.warpWidth - this.controlBoxLeft) + 'px'; } if (allHeight > this.warpHeight) { myStyle.height = (this.warpHeight - this.controlBoxTop) + 'px'; } // 限制最小寬度 if ( parseInt(myStyle.width) < minWidth)myStyle.width = minWidth + 'px'; if (parseInt(myStyle.height) < minHeight) myStyle.height = minHeight + 'px'; // 右上角 } else if (this.draging == this.resizeTr) { // 需要改變的寬度,該變高度即改變TOP的坐標 changeWidth = posx - this.controlBoxWidth - this.controlBoxLeft; // 計算總寬度 allWidth = this.controlBoxWidth + changeWidth + this.controlBoxLeft; // 改變寬度 myStyle.width = (this.controlBoxWidth + changeWidth) + 'px'; if (allWidth > this.warpWidth) myStyle.width = ( this.warpWidth - this.controlBoxLeft) + 'px'; if ( parseInt(myStyle.width) < minWidth) myStyle.width = minWidth + 'px'; // 改變高度 my.style.top = posy + 'px'; my.style.height = (this.controlBoxHeight + (this.controlBoxTop - posy)) +'px'; if(parseInt(my.style.height)< minHeight){ my.style.height = minHeight +'px'; my.style.top = (this.lb_y - minHeight) + 'px'; } if(parseInt(my.style.height)>this.lb_y){ my.style.height = this.lb_y + 'px'; my.style.top = 0; } // 左上角 }else if (this.draging == this.resizeLt) { changeWidth = this.controlBoxLeft - posx; changeHeight = this.controlBoxTop - posy; my.style.left = posx + 'px'; my.style.width = (this.controlBoxWidth + changeWidth) + 'px'; my.style.top = posy + 'px'; my.style.height = (this.controlBoxHeight + changeHeight) + 'px'; // 限制寬高度最大值 if(parseInt(my.style.width) > this.controlBoxLeft + this.controlBoxWidth){ my.style.width = (this.controlBoxLeft + this.controlBoxWidth) + 'px'; my.style.left = 0; }else if(parseInt(my.style.width)< minWidth){ my.style.left = (this.rb_x - minWidth) + 'px'; my.style.width = minWidth + 'px'; } if(parseInt(my.style.height) > this.controlBoxHeight + this.controlBoxTop){ my.style.height = (this.controlBoxHeight + this.controlBoxTop) + 'px'; if(parseInt(my.style.top)<0) my.style.top = 0; }else if(parseInt(my.style.height)< minHeight){ my.style.top = (this.rb_y - minHeight) + 'px'; my.style.height = minHeight + 'px'; } // 左下角 }else if(this.draging == this.resizeBl){ changeWidth = this.controlBoxLeft - posx; changeHeight = posy - this.controlBoxHeight - this.controlBoxTop; my.style.left = posx + 'px'; my.style.width = this.controlBoxWidth + changeWidth + 'px'; my.style.height = this.controlBoxHeight + changeHeight + 'px'; if(parseInt(my.style.width)< minWidth){ my.style.width = minWidth + 'px'; my.style.left = this.lt_x - minWidth + 'px'; }else if(parseInt(my.style.width)> this.lt_x){ my.style.width = this.lt_x + 'px'; my.style.left = 0; } if(parseInt(my.style.height)< minHeight){ my.style.height = minHeight + 'px'; }else if(parseInt(my.style.height)> this.warpHeight- this.lt_y){ my.style.height = this.warpHeight- this.lt_y +'px'; } } break; case 'mouseup': this.draging = null; break; } }, bind:function () { var that = this; bindEvent(document, 'mousedown', bindFunction(that,that.moveBox)); bindEvent(document, 'mousemove', bindFunction(that,that.moveBox)); bindEvent(document, 'mouseup', bindFunction(that,that.moveBox)); } }; var demo = new DragBox({ outWarpId:'outwarp' }); })() </script> </body> </html>