拥有高自定义的jQuery拖动插件

拥有高自定义的jQuery拖动插件
/// 
/*TGL.Drag.js
 *拖动、改变大小基本功能代码
 *要求:引入jquery
 *调用:$().tglDrag()、$().tglResize()、$().EasyDrag()、$().EasyResize()
 *tgl起头的两个函数具备高度自定义,并且没有绑定触发事件的事件,完全由自己绑定触发
 *
 */

(function() {
    var currentElement;
    var currentDR = "";
    var lastXY = { X: 0, Y: 0 };
    var beginInfo = { L: 0, T: 0, W: 0, H: 0, X: 0, Y: 0 };

    function getOffset(e) {
        var tempx = lastXY.X,
        tempy = lastXY.Y;
        lastXY.X = e.pageX;
        lastXY.Y = e.pageY;
        //返回近两次间的偏移量offset及当前与原始间的偏移量
        return { offsetX: lastXY.X - tempx, offsetY: lastXY.Y - tempy, intactOffsetX: lastXY.X - beginInfo.X, intactOffsetY: lastXY.Y - beginInfo.Y };
    };

    function endDrag(e) {
        currentElement = null;
        delete (beginInfo);
        beginInfo = { L: 0, T: 0, W: 0, H: 0, X: 0, Y: 0 };
        delete (lastXY);
        lastXY = { X: 0, Y: 0 };
    };
    function beginDrag(e) {
        var _this = currentElement = this;
        var $this = this[currentDR + "Option"].RealityDom || this;
        $this = $this.jquery ? $this : $($this);
        lastXY = { X: 0, Y: 0 };
        beginInfo.X = getOffset(e);
        beginInfo.Y = beginInfo.X.offsetY;
        beginInfo.X = beginInfo.X.offsetX;

        beginInfo.H = $this.height();
        beginInfo.W = $this.width();

        beginInfo.L = $this.offset();
        beginInfo.T = beginInfo.L.top;
        beginInfo.L = beginInfo.L.left;

        this.OldState = beginInfo;
        return beginInfo;

    };
    $(document).mousemove(function(e) {
        if (currentElement) {
            var offset = getOffset(e);
            currentElement[currentDR + "Option"][currentDR + "ing"].call(currentElement, e, offset);
            return false;
        }
    });

    function baseBind(option, dr) {

        this[dr + "Start"] = function() {
            currentDR = dr;
            if (typeof option["Begin" + dr] == "function")
                if (option["Begin" + dr].apply(this, arguments) === false)
                return false;
            return beginDrag.apply(this, arguments);
        };

        this[dr + "Stop"] = function() {
            if (typeof option["End" + dr] == "function")
                option["End" + dr].apply(this, arguments);
            return endDrag.apply(this, arguments);
        }

        this[dr + "Option"] = option;
    };
    //调用tglDrag[tglResize]后,在任何时候执行对应dom对象的DragStart[ResizeStart]函数就可以触发移动[改变大小],执行
    $.each(["Drag", "Resize"], function(n, v) {
        $.fn["tgl" + v] = function(option) {
            option = $.extend({}, option);
            //移动边界规则,最终采用调用函数返回方式,以便灵活定义规则
            option.PositionRule = $.extend({
                max: [Number.MAX_VALUE, Number.MAX_VALUE],
                min: [-Number.MAX_VALUE, -Number.MAX_VALUE]
            }, option.PositionRule);
            $.each(option.PositionRule, function(n, v) {
                $.each(v, function(n1) {
                    if (typeof option.PositionRule[n][n1] != "function") {
                        var _temp = option.PositionRule[n][n1];
                        option.PositionRule[n][n1] = function(e, offset) {
                            return _temp;
                        }
                    }
                });
            });

            //大小限制规则,最终采用调用函数返回方式,以便灵活定义规则
            option.SizeRule = $.extend({ max: [Number.MAX_VALUE, Number.MAX_VALUE], min: [0, 0] }, option.SizeRule);
            $.each(option.SizeRule, function(n) {
                $.each(option.SizeRule[n], function(n1) {
                    if (typeof option.SizeRule[n][n1] != "function") {
                        var _temp = option.SizeRule[n][n1];
                        option.SizeRule[n][n1] = function(e, offset) {
                            return _temp;
                        }
                    }
                });
            });

            if (typeof (option[v + "ing"]) != "function")
                option[v + "ing"] = v == "Drag" ? baseDraging : baseResizing;
            return this.each(function() {
                baseBind.call(this, option, v);
                return this;
            });
        }
    });


    //系统默认拖动方法
    function baseDraging(e, offset) {
        var of = $(this).offset();
        var pr = this.DragOption.PositionRule;
        var $this = $(this);
        $this.css({
            left: Math.max(Math.min(this.OldState.L + offset.intactOffsetX, pr.max[0].call($this, e, offset)), pr.min[0].call($this, e, offset)),
            top: Math.max(Math.min(this.OldState.T + offset.intactOffsetY, pr.max[1].call($this, e, offset)), pr.min[1].call($this, e, offset))
        });
    }


    jQuery.fn.EasyDrag = function(option) {
        option = $.extend({
            Draging: baseDraging
        }, option);
        return this.each(function() {
            var $this = $(this);
            var _this = this;
            var handler = $this;

            //handler默认为自身,可以通过option中的handler设置,
            //1、设置为jQuery对象:handler=option.handler
            //2、selector的string对象:handler=$this.find(option.handler)
            //3、dom: $(option.handler)
            //4、function:option.handler.call($this, option)
            if (option && option.handler) {
                var temptype = typeof option.handler;
                if (temptype == "function")
                    handler = option.handler.call($this, option);
                else if (temptype == "string")
                    handler = $this.find(option.handler);
                else
                    handler = option.handler.jquery ? option.handler : $(option.handler);
            }
            if (handler.length == 0)
                handler = $this;

            handler.css("cursor", "move");
            handler.mousedown(function(e) {
                if (typeof option.Drag == "function")
                    if (option.Drag.call(_this) === false)
                    return;
                _this.DragStart(e);
                $(document).one("mouseup", function(e) {
                    _this.DragStop(e);
                });
                return false;
            });
            $this.tglDrag(option);
            //baseBind.call(, option, "Drag");
        });
    };

    //系统默认改变大小方法
    function baseResizing(e, offset) {
        var of = $(this).offset();
        var temp = this.ResizeOption.SizeRule;
        var r = this.OldState.W + this.OldState.L;
        var b = this.OldState.H + this.OldState.T;
        var $this = $(this);
        $this.css({
            width: Math.max(Math.min(this.OldState.W + offset.intactOffsetX * this.resizeHorizontal, temp.max[0].call($this)), temp.min[0].call($this)),
            left: this.resizeHorizontal == -1 ? Math.max(Math.min(this.OldState.L + offset.intactOffsetX, r - temp.min[0].call($this)), r - temp.max[0]()) : of.left,
            height: Math.max(Math.min(this.OldState.H + offset.intactOffsetY * this.resizeVertical, temp.max[1].call($this, e, offset)), temp.min[1].call($this, e, offset)),
            top: this.resizeVertical == -1 ? Math.max(Math.min(this.OldState.T + offset.intactOffsetY, b - temp.min[1].call($this)), b - temp.max[1].call($this)) : of.top
        });
    };

    //设置resize
    function setCursor(e, option) {
        var $this = $(this);
        var offset = $this.offset();
        offset.width = $this.width();
        offset.height = $this.height();

        this.resizeHorizontal = Math.abs(e.pageX - offset.left) < option.ResizeStandard ? -1 : Math.abs(e.pageX - (offset.left + offset.width)) < option.ResizeStandard ? 1 : 0;
        this.resizeVertical = Math.abs(e.pageY - offset.top) < option.ResizeStandard ? -1 : Math.abs(e.pageY - (offset.top + offset.height)) < option.ResizeStandard ? 1 : 0;
        var temp = (this.resizeVertical == 1 ? "s" : "")
            + (this.resizeVertical == -1 ? "n" : "")
            + (this.resizeHorizontal == -1 ? "w" : "")
            + (this.resizeHorizontal == 1 ? "e" : "");
        if (temp != "")
            $this.css("cursor", temp + "-resize");
        else
            $this.css("cursor", $this.data("cursor"));

        return !(this.resizeVertical == 0 && this.resizeHorizontal == 0);
    }

    $.fn.EasyResize = function(option) {
        option = $.extend({
            Resizeing: baseResizing,
            ResizeStandard: 5
        }, option);

        //大小限制规则,最终采用调用函数返回方式,以便灵活定义规则
        option.SizeRule = $.extend({ max: [Number.MAX_VALUE, Number.MAX_VALUE], min: [0, 0] }, option.SizeRule);
        $.each(option.SizeRule, function(n) {
            $.each(option.SizeRule[n], function(n1) {
                if (typeof option.SizeRule[n][n1] != "function") {
                    var _temp = option.SizeRule[n][n1];
                    option.SizeRule[n][n1] = function(e, offset) {
                        return _temp;
                    }
                }
            });
        });

        return this.each(function() {
            var $this = $(this);
            var _this = this;
            $this.data("cursor", $this.css("cursor"));
            function _move(e) {
                setCursor.call(_this, e, option);
            }
            $this.mousemove(_move).mousedown(function(e) {
                if (!setCursor.call(_this, e, option))
                    return;
                $this.unbind("mousemove", _move);
                _this.ResizeStart(e);
                $(document).one("mouseup", function(e) {
                    _this.ResizeStop(e);
                    $this.unbind("mousemove", _move).bind("mousemove", _move);
                });
                return false;
            });

            baseBind.call(_this, option, "Resize");
        })
    }
} (jQuery));



【下载】
posted @ 2009-06-23 23:09  TGL  阅读(1831)  评论(0编辑  收藏  举报