JS拖拽系列--多元素拖拽,面向对象,es6拖拽
最近不太忙,终于有时间,研究了一下早就想搞定的拖拽系列,先是写了面向过程式的,再做一个面向对象的,再顺便弄弄继承,最后玩一下ES6的class 不觉用了一天多,收获很大。拖拽弄完,想再弄一个拖放。 上代码:
函数式简单版:
<style type="text/css"> #div1 { position: absolute; height: 100px; width: 100px; background: #ccc; } </style> <div id="div1"> sdasd </div> <p>sdfsfsdfsdfsz</p> <script> var log = console.log.bind(this); ;(function(win, doc) { var drag = function(obj, options, callback) { obj.onmousedown = function(ev) { var oEvent = ev || window.event; var disX = oEvent.offsetX; var disY = oEvent.offsetY; doc.onmousemove = function(ev) { var oEvent = ev || window.event; var x = oEvent.clientX - disX; var y = oEvent.clientY - disY; obj.style.left = x + 'px'; obj.style.top = y + 'px'; } doc.onmouseup = function() { doc.onmousedown = null; doc.onmousemove = null; obj.releaseCapture && obj.releaseCapture(); } obj.setCapture && obj.setCapture(); return false; } }; win.drag = drag; })(window, document); var div1 = document.getElementById('div1'); drag(div1); </script>
面向对象+继承:
<style type="text/css"> #div1 { position: absolute; height: 100px; width: 100px; background: #ccc; } .drag_box { height: 100px; width: 100px; background: rgb(254, 171, 121); position: absolute; } </style> <div id="div1"> sdasd </div> <p>sdfsfsdfsdfsz <br /> sdadas </p> <div class="drag_box"> 多box拖拽 </div> <div class="drag_box"> 多box拖拽 </div> <a href="javascript:;">dsadasd</a> <script> var log = console.log.bind(this); ; (function() { window.Drag = function Drag(cls) { this.obj = Array.prototype.slice.call(document.querySelectorAll(cls)); this.win_w = document.documentElement.clientWidth || document.body.clientWidth; this.win_h = document.documentElement.clientHeight || document.body.clientHeight; } Drag.prototype.init = function(user_config) { //默认参数 var defaults = { isLimit: false, isChangeIndex: false } this.config = this.extend(defaults, user_config); var _this = this; for(var i = 0; i < this.obj.length; i++) { (function(i) { _this.obj[i].onmousedown = function() { this.disX; this.disY; var pos = document.defaultView.getComputedStyle(_this.obj[i], false).Position; if(!pos || pos.toLowerCase() == 'static') { _this.obj[i].style.position = 'absolute' }; var e = e || window.event; _this.mousedown(_this.obj[i], e); return false } })(i); } } Drag.prototype.extend = function(a, b) { for(var key in b) { if(b.hasOwnProperty(key)) { a[key] = b[key]; } } return a; } Drag.prototype.mousedown = function(ele, e) { var _this = this; var e = e || window.event; this.disX = e.offsetX; this.disY = e.offsetY; if(this.config.isChangeIndex) { for(var i = 0; i < this.obj.length; i++) { this.obj[i].style.zIndex = 'auto' } ele.style.zIndex = 100; } document.onmousemove = function(e) { var e = e || window.event; _this.mousemove(ele, e); } document.onmouseup = function(e) { var e = e || window.event; _this.mouseup(ele, e) } } Drag.prototype.mousemove = function(ele, e) { var l = e.clientX - this.disX; var t = e.clientY - this.disY; if(this.config.isLimit) { var w = this.win_w - ele.offsetWidth; var h = this.win_h - ele.offsetHeight; ele.style.left = l <= 0 ? 0 : (l > w ? (w + 'px') : (l + 'px')); ele.style.top = t <= 0 ? 0 : (t >= h ? (h + 'px') : (t + 'px')); } else { ele.style.left = l + 'px'; ele.style.top = t + 'px'; } } Drag.prototype.mouseup = function(ele, e) { document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; if(this.config.isChangeIndex) { ele.style.zIndex = 100; } return false }; })(); //继承出LimitDrag ; (function() { // 限制范围拖拽 window.LimitDrag = function LimitDrag(cls) { Drag.call(this, cls) } LimitDrag.prototype = new Drag(); LimitDrag.prototype.constructor = LimitDrag; //限制范围 LimitDrag.prototype.mousemove = function(ele, e) { var l = e.clientX - this.disX; var t = e.clientY - this.disY; var w = this.win_w - ele.offsetWidth; var h = this.win_h - ele.offsetHeight; ele.style.left = l <= 0 ? 0 : (l > w ? (w + 'px') : (l + 'px')); ele.style.top = t <= 0 ? 0 : (t >= h ? (h + 'px') : (t + 'px')); ele.style.zIndex = 100; } })(); window.onload = function() { new Drag('#div1').init({ }); new Drag('a').init({ }); new Drag('.drag_box').init({ isLimit: true, isChangeIndex: true }); new LimitDrag('p').init({ isLimit: true, isChangeIndex: true }); } </script>
面向对象ES6:
<style type="text/css"> #div1 { position: absolute; height: 100px; width: 100px; background: #ccc; } .drag_box { height: 100px; width: 100px; background: rgb(254, 171, 121); position: absolute; } </style> <div id="div1"> sdasd </div> <p>sdfsfsdfsdfsz <br /> sdadas </p> <div class="drag_box"> 多box拖拽 </div> <div class="drag_box" style="left: 300px;"> 多box拖拽 </div> <script> var log = console.log.bind(this); // es6 class class Drag { constructor(cls) { this.obj = document.querySelectorAll(cls); this.win_w = document.documentElement.clientWidth || document.body.clientWidth; this.win_h = document.documentElement.clientHeight || document.body.clientHeight; } init(user_config) { var defaults = { isLimit: false, isChangeIndex: false } this.config = this.extend(defaults, user_config); for(let i = 0; i < this.obj.length; i++) { this.disX; this.disY; this.obj[i].onmousedown = (e => { var e = e || window.event; this.mousedown(e, this.obj[i]); }) } } extend(a, b) { for(let attr in b) { if(b.hasOwnProperty(attr)) { a[attr] = b[attr] } } return a; } mousedown(e, ele) { this.disX = e.offsetX; this.disY = e.offsetY; var _this = this; var pos = document.defaultView.getComputedStyle(ele, false).Position; if(!pos || pos.toLowerCase() == 'static') { ele.style.position = 'absolute' }; if(this.config.isChangeIndex) { for(let i = 0; i < this.obj.length; i++) { this.obj[i].style.zIndex = 'auto' } ele.style.zIndex = 100; } document.onmousemove = function(e) { var e = e || window.event; _this.mousemove(e, ele); return false } document.onmouseup = function() { _this.mouseup(ele) } } mousemove(e, ele) { let l = e.clientX - this.disX; let t = e.clientY - this.disY; if(this.config.isLimit) { let w = this.win_w - ele.offsetWidth; let h = this.win_h - ele.offsetHeight; ele.style.left = l <= 0 ? 0 : (l > w ? (w + 'px') : (l + 'px')); ele.style.top = t <= 0 ? 0 : (t >= h ? (h + 'px') : (t + 'px')); } else { ele.style.left = l + 'px'; ele.style.top = t + 'px'; } return false; } mouseup(ele) { document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; if(this.config.isChangeIndex) { ele.style.zIndex = 100; } return false; } } class chixingDrag extends Drag { constructor(...arg) { super(...arg) } mousemove(e, ele) { let l = e.clientX - this.disX; let t = e.clientY - this.disY; if(this.config.isLimit) { let w = this.win_w - ele.offsetWidth; let h = this.win_h - ele.offsetHeight; ele.style.left = l <= 50 ? 0 : (l > (w - 50) ? (w + 'px') : (l + 'px')); ele.style.top = t <= 50 ? 0 : (t >= (h - 50) ? (h + 'px') : (t + 'px')); } else { ele.style.left = l + 'px'; ele.style.top = t + 'px'; } return false; } } window.onload = function() { var drag1 = new Drag('#div1').init({ isLimit: true }); new chixingDrag('.drag_box').init({ isLimit: true, isChangeIndex: true }); } </script>
参数说明:
isLimit: true,//是否限制范围,默认false
isChangeIndex: true //是否改变z-index,默认false,也就是多文件拖拽的时候是否新挪动的在最上边。
tips:关于setCapture,releaseCapture不是很懂,说了为了兼容IE,这里的问题暂时不考虑了。