1.基于jquery

2.效率优先

3.可配置项(拖动者,鼠标样式)

欢迎PK效率!!

/**
 * dragsort.js
 *
 * @example
 *     new DH.Widget.Dragsort({
 *         el : 'string' // 拖动容器, 必填项
 *         dragSelector : 'string', // 拖动元素选择器, 非必填项
 *         moveSelector : 'string', // 被拖动元素选择器, 非必填项
 *         moveClassName : 'string', // 被多动元素类
 *         placeHolder : 'string', // 占位符元素, 如: <div>, 非必填项
 *         cursor : 'string', // 拖动鼠标样式, 非必填项
 *         zIndex : number, // 被拖动元素z-index, 非必填项, 默认999
 *         opacity : number // 被拖动元素透明度, 非必填项, 默认 0.5
 *     })
 * 
 */
(function($){

    var Dragsort = DH.Base.create({

        init : function(){

            if(!this.el) return;

            var firstChild = this.el.children().get(0).nodeName.toLowerCase();

            this.dragSelector = this.options.dragSelector || firstChild;

            this.moveSelector = this.options.moveSelector || firstChild;

            this.moveClassName = this.options.moveClassName;

      this.$place = this.options.placeHolder && $(this.options.placeHolder) || $('<' + firstChild + '>');

            this.cursor = this.options.cursor || 'move';

            this.zIndex = this.options.zIndex || 999;

            this.opacity = this.options.opacity || 0.5;

            this.dragFn = this.proxy(this.drag);

            this.el.delegate(this.dragSelector, 'mousedown', this.dragFn);

        },
        drag : function(e){

            var $e = $(e.currentTarget),
                $drag = this.$drag = $e,
                $move = this.$move = $e.closest(this.moveSelector + ':visible'),
                $place = this.$place,
                pageX = e.pageX,
                pageY = e.pageY,
                position = $move.position(),
                offset = $move.offset(),
                left = position.left,
                top = position.top
                ;

            $drag
                .css({
                    cursor : this.cursor
                })
                ;

            $move.find('td').length && $move.find('td').each(function(){
                $(this).width($(this).width());
            });

            $move
                .css({
                    position : 'absolute',
                    left : left,
                    top : top,
                    width : $move.width(),
                    height : $move.height(),
                    zIndex : this.zIndex,
                    opacity : this.opacity,
                    '-moz-user-select' : 'none' // stop moz text select
                })
                .after($place)
                ;

            this.moveClassName && $move.addClass(this.moveClassName);

            $place
                .show()
                .css({
                    width : $move.width(),
                    height : $move.height()
                })
                .addClass('dragsort-placeholder')
                ;

            this.start = {
                left : pageX - left,
                top : pageY - top
            }

            this.sortFn = this.proxy(this.sort);
            this.stopFn = this.proxy(this.stop);

            $(document)
                .bind('mousemove', this.sortFn)
                .bind('mouseup', this.stopFn)
                .bind('selectstart', this.stopBubble) // stop ie text select
                ;

            this.canDrag = true;

            return false; // 阻止拖动元素事件冒泡

        },
        sort : function(e){

            if(!this.canDrag) return;

            var $move = this.$move,
                $place = this.$place,
                pageX = e.pageX,
                pageY = e.pageY,
                start = this.start,
                left = pageX - start.left,
                top = pageY - start.top,
                position = $move.position(),
                hw = $move.width() / 2,
                hh = $move.height() / 2,
                $prevs = $move.prevAll().not(':hidden'),
                $nexts = $move.nextAll().not('.dragsort-placeholder').not(':hidden')
                ;

            $move.css({
                left : left,
                top : top
            });


            $prevs.length && $prevs.each(function(){
                var $this = $(this),
                    tposition = $this.position()
                    ;

                if(position.left - hw < tposition.left && position.top - hh < tposition.top){
                    $place.after($this);
                    $place.before($move);
                }
            });

            $nexts.length && $nexts.each(function(){
                var $this = $(this),
                    tposition = $this.position()
                    ;

                if(position.left + hw > tposition.left && position.top + hh > tposition.top){
                    $this.after($place);
                    $place.before($move);
                }
            });

        },
        stop : function(){

            var $drag = this.$drag,
                $move = this.$move,
                $place = this.$place
                ;

            this.canDrag = false;

            $(document)
                .unbind('mousemove', this.sortFn)
                .unbind('mouseup', this.stopFn)
                .unbind('selectstart', this.stopBubble)
                ;

            this.sortFn = null;
            this.stopFn = null;

            $drag
                .css({
                    cursor : ''
                })
                ;

            $move.find('td').length && $move.find('td').each(function(){
                $(this).width('');
                $(this).attr('style') === '' && $(this).removeAttr('style');
            });

            $move
                .css({
                    position : '',
                    left : '',
                    top : '',
                    width : '',
                    height : '',
                    zIndex : '',
                    opacity : '',
                    '-moz-user-select' : ''
                })
                ;

            this.moveClassName && $move.removeClass(this.moveClassName);

            $move.attr('style') === '' && $move.removeAttr('style');

            $move.attr('class') === '' && $move.removeAttr('class');

            $place.after($move).hide();

            this.trigger('stop');

        },
        stopBubble: function(){
            return false; 
        },
        once : function(){

            this.bind('stop', this.proxy(this.destory));
            this.trigger('once');

        },
        destory : function(){

            this.el.undelegate(this.dragSelector, 'mousedown', this.dragFn);
            this.dragFn = null;
            this.el = null;
            this.trigger('destory');
            this.$place.remove();
            this.$place = null;
            this.$drag = null;
            this.$move = null;

        }

    });

    DH.Widget.Dragsort = Dragsort;

})(window.jQuery);

 

 

 

 posted on 2014-04-18 19:31  jacklau  阅读(1076)  评论(0编辑  收藏  举报