1.基于jquery
2.效率优先
3.可配置项(拖动者,鼠标样式,拖动范围)
欢迎PK效率!!
/** * dragdrop.js * * @example * * new DH.Widget.Dragdrop({ * el : 'string', // 被拖动元素选择器, 必须项 * dragSelector : 'string', // 拖动选择器, 非必须项 * opacity : 'number', // 拖动时透明度, 非必须项 * cursor : 'string', // 鼠标样式, 非必须项 * delay : true || false, // 是否延迟, 非必须项 * animate : true || false, // 延迟后是否动画, 非必须项 * speed : number, // 动画执行速度,越小越快,单位毫秒, 非必须项 * scopeSelector : 'string' // 被拖动元素移动范围, 非必须项 * }) * */ (function($){ var Dragdrop = DH.Base.create({ init : function(){ if(!this.el || !this.el.length) return; this.begin = {}; this.canDrag = false; this.$drag = this.options.dragSelector ? this.el.find(this.options.dragSelector) : this.el; // 拖动元素 this.$scope = this.options.scopeSelector && $(this.options.scopeSelector); // 拖动范围 this.$move = this.el; // 移动元素 this.cursor = this.options.cursor || 'move'; // 鼠标样式 this.opacity = this.options.opacity || 1; // 拖动是透明度 this.delay = !!this.options.delay; // 是否延迟 this.animate = !!this.options.animate; // 是否动画 this.speed = this.options.speed || 200; // 动画移动速度,默认200毫秒 this.dragFn = this.proxy(this.drag); this.resetFn = this.proxy(this.reset); this.$drag.bind('mousedown', this.dragFn); $(window).bind('resize', this.resetFn); this.reset(); }, drag : function(e){ var $move = this.$move, $drag = this.$drag, $scope = this.$scope, pageX = e.pageX, pageY = e.pageY, left = parseFloat($move.css('left')), top = parseFloat($move.css('top')) ; isNaN(left) && (left = 0); // fixed ie isNaN(top) && (top = 0); // fixed ie this.begin = { left : pageX - left, top : pageY - top }; $drag.css('cursor', this.cursor); $move.css('-moz-user-select', 'none'); // stop moz text select $move.css('opacity', this.opacity); if(this.delay){ if(!this.$delay){ var $delay = this.$delay = $('<div>').appendTo($move.parent()); $delay.css({ position : 'absolute', cursor : this.cursor, border : '1px dotted #333', width : $move.outerWidth(true), height : $move.outerHeight(true), left : left, top : top,
zIndex : parseInt($move.css('zIndex')) + 1 }); }else{ this.$delay.show(); } } this.moveFn = this.proxy(this.move); this.stopFn = this.proxy(this.stop); $(document) .bind('mousemove', this.moveFn) .bind('mouseup', this.stopFn) .bind('selectstart', this.stopBubble); // stop ie text select ; this.canDrag = true; this.trigger('drag', $move, left, top); }, move : function(e){ if(!this.canDrag) return; var $move = this.$move, $scope = this.$scope, pageX = e.pageX, pageY = e.pageY, begin = this.begin, left = pageX - begin.left, top = pageY - begin.top ; if(this.defaults){ var defaults = this.defaults; if(left < defaults.minLeft){ left = defaults.minLeft; }else if(left > defaults.maxLeft){ left = defaults.maxLeft; } if(top < defaults.minTop){ top = defaults.minTop; }else if(top > defaults.maxTop){ top = defaults.maxTop; } } if(this.delay){ this.$delay.css({ left : left, top : top }); }else{ $move.css({ left : left, top : top }); } this.trigger('move', $move, left, top); }, stop : function(){ var $move = this.$move, $drag = this.$drag, left = parseFloat($move.css('left')), top = parseFloat($move.css('top')) ; if(this.delay){ var $delay = this.$delay, left = parseFloat($delay.css('left')), top = parseFloat($delay.css('top')) ; if(this.animate){ $move.animate({ left : left, top : top }, this.speed, function(){ $delay.hide(); }); }else{ $move.css({ left : left, top : top }); $delay.hide(); } } $drag.css('cursor', ''); $move.css('-moz-user-select', ''); $move.css('opacity', ''); $(document) .unbind('mousemove', this.moveFn) .unbind('mouseup', this.stopFn) .unbind('selectstart', this.stopBubble); ; this.canDrag = false; this.trigger('stop', $move, left, top); }, stopBubble: function(){ return false; }, /** * 计算移动元素的活动范围 [description] */ reset : function(){ if(this.$scope){ var $move = this.$move, $scope = this.$scope, minLeft = 0, maxLeft = $move.width(), minTop = 0, maxTop = $move.height(), offset = $move.offset(), oleft = offset.left, otop = offset.top, position = $move.position(), pleft = position.left, ptop = position.top, eleft = parseFloat($move.css('left')), etop = parseFloat($move.css('top')), scopeOffset = $scope.position(), scopeLeft = scopeOffset.left, scopeTop = scopeOffset.top, scopeWith = $scope.width(), scopeHeight = $scope.height(), width = $move.width(), height = $move.height() ; if(parseFloat($scope.css('marginLeft')) > 0){ scopeLeft += parseFloat($scope.css('marginLeft')); } if(parseFloat($scope.css('marginTop')) > 0){ scopeTop += parseFloat($scope.css('marginTop')); } minLeft = scopeLeft - (oleft - pleft); maxLeft = scopeLeft - (oleft - pleft) + scopeWith - width; minTop = scopeTop - (otop - ptop); maxTop = scopeTop - (otop - ptop) + scopeHeight - height; this.defaults = { minLeft : minLeft, maxLeft : maxLeft, minTop : minTop, maxTop : maxTop } } }, destory : function(){ this.stop(); this.$drag.unbind('mousedown', this.dragFn); $(window).unbind('resize', this.resetFn); this.$drag = null; this.$move = null; this.$scope = null; this.start = null; this.defaults = null; } }); DH.Widget.Dragdrop = Dragdrop; })(window.jQuery);