MyDrag

DIV拖动库,稳定高效,专为您解决DIV拖动的烦恼

目前為 2020-09-28 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/412159/852345/MyDrag.js

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         MyDrag
// @namespace    http://bbs.91wc.net/
// @version      0.1.0
// @description  DIV拖动库,稳定高效,专为您解决DIV拖动的烦恼
// @author       Wilson
// ==/UserScript==

var MyDrag = (function(){
    function Drag(){
        //初始化
        this.initialize.apply(this, arguments)
    }
    Drag.prototype = {
        //初始化
        initialize : function (drag, options){
            this.drag = this.$(drag);
            this.drag.style.width = (parseInt(this.drag.style.width)||this.drag.offsetWidth);
            this._x = this._y = 0;
            this._moveDrag = this.bind(this, this.moveDrag);
            this._stopDrag = this.bind(this, this.stopDrag);
            this.setOptions(options);
            this.handle = this.$(this.options.handle);
            this.maxContainer = this.$(this.options.maxContainer);
            this.maxTop = Math.max(this.maxContainer.clientHeight, this.maxContainer.scrollHeight) - this.drag.offsetHeight + (parseInt(this.maxContainer.style.marginTop)||0);
            this.maxLeft = Math.max(this.maxContainer.clientWidth, this.maxContainer.scrollWidth) - this.drag.offsetWidth + (parseInt(this.maxContainer.style.marginLeft)||0);
            this.limit = this.options.limit;
            this.lockX = this.options.lockX;
            this.lockY = this.options.lockY;
            this.lock = this.options.lock;
            this.onStart = this.options.onStart;
            this.onMove = this.options.onMove;
            this.onStop = this.options.onStop;
            this.handle.style.cursor = "move";
            this.changeLayout();
            this.addHandler(this.handle, "mousedown", this.bind(this, this.startDrag))
        },
        changeLayout : function (){
            this.drag.style.top = this.drag.offsetTop + "px";
            this.drag.style.left = this.drag.offsetLeft + "px";
            this.drag.style.position = "absolute";
            this.drag.style.margin = "0"
        },
        startDrag : function (event){       
            var event = event || window.event;
            this._x = event.clientX - this.drag.offsetLeft;
            this._y = event.clientY - this.drag.offsetTop;
            this.addHandler(document, "mousemove", this._moveDrag);
            this.addHandler(document, "mouseup", this._stopDrag);
            event.preventDefault && event.preventDefault();
            this.handle.setCapture && this.handle.setCapture();
            this.onStart()
        },
        moveDrag : function (event){
            var event = event || window.event;
            var iTop = event.clientY - this._y;
            var iLeft = event.clientX - this._x;
            if (this.lock) return;
            this.limit && (iTop < 0 && (iTop = 0), iLeft < 0 && (iLeft = 0), iTop > this.maxTop && (iTop = this.maxTop), iLeft > this.maxLeft && (iLeft = this.maxLeft));
            var initTop = parseInt(this.maxContainer.style.marginTop) || 0;
            iTop = iTop < initTop ? initTop : iTop;
            var initLeft = parseInt(this.maxContainer.style.marginLeft) || 0;
            iLeft = iLeft < initLeft ? initLeft : iLeft;
            this.lockY || (this.drag.style.top = iTop + "px");
            this.lockX || (this.drag.style.left = iLeft + "px");
            var iWinWidth = document.documentElement.clientWidth;
            var iWinHeight = document.documentElement.clientHeight;
            if(this.drag.offsetLeft<0){
                this.drag.style.left =0+'px';
            }else if(this.drag.offsetLeft>(iWinWidth-this.drag.offsetWidth)){
                this.drag.style.left =iWinWidth-this.drag.offsetWidth+'px';
            }
            if(this.drag.offsetTop<0){
                this.drag.style.top =0+'px';
            }else if(this.drag.offsetTop>(iWinHeight-this.drag.offsetHeight)){
                this.drag.style.top =iWinHeight-this.drag.offsetHeight+'px';
            }
            event.preventDefault && event.preventDefault();
            this.onMove()
        },
        stopDrag : function (){
            this.removeHandler(document, "mousemove", this._moveDrag);
            this.removeHandler(document, "mouseup", this._stopDrag);
             
            this.handle.releaseCapture && this.handle.releaseCapture();
             
            this.onStop()
        },
        //参数设置
        setOptions : function (options){
            this.options ={
                handle:           this.drag, //事件对象
                limit:            true, //锁定范围
                lock:             false, //锁定位置
                lockX:            false, //锁定水平位置
                lockY:            false, //锁定垂直位置
                maxContainer:     document.documentElement || document.body, //指定限制容器
                onStart:          function () {}, //开始时回调函数
                onMove:           function () {}, //拖拽时回调函数
                onStop:           function () {}  //停止时回调函数
            };
            for (var p in options) this.options[p] = options[p]
        },
        //获取id
        $ : function (id)
        {
            return typeof id === "string" ? document.getElementById(id) : id
        },
        //添加绑定事件
        addHandler : function (oElement, sEventType, fnHandler)
        {
            return oElement.addEventListener ? oElement.addEventListener(sEventType, fnHandler, false) : oElement.attachEvent("on" + sEventType, fnHandler)
        },
        //删除绑定事件
        removeHandler : function (oElement, sEventType, fnHandler)
        {
            return oElement.removeEventListener ? oElement.removeEventListener(sEventType, fnHandler, false) : oElement.detachEvent("on" + sEventType, fnHandler)
        },
        //绑定事件到对象
        bind : function (object, fnHandler)
        {
            return function ()
            {
                return fnHandler.apply(object, arguments)   
            }
        }
    };
    return Drag;
})();

/**
//使用示例:
//这里样式仅仅为了演示好看,实际上只需要设置box宽度就好了,如果没设置宽度,div默认100%,不利于看到效果
body,div,h2,p{margin:0;padding:0}
body{font:14px/1.5 arial}
#box{width:300px;height:100px;background:#fef4eb;padding:5px;border:1px solid #666}
#box #title{height:25px;background:#ccc;display:inline-block;cursor:move;width:100%;text-align:center}
.content{text-align:center;line-height:50px}
<div id="box">
    <span id="title">按下我拖拽</span>
    <div class='content'>内容区</div>
</div>
//调用
var box = document.getElementById("box");    
var title = document.getElementById("title");  
new MyDrag(box, {handle:title});
//box是拖拽最外层的div,title是按下时控制句柄的div

//其他参数
handle:           //拖动控制句柄,就是上面示例的title
limit:            //是否限制拖动范围,默认是true
maxContainer:     //拖动限制范围的容器,默认是body,可设置在某个div内拖动
lock:             //是否锁定位置,默认false,锁定后无法拖动
lockX:            //是否锁定水平位置,默认false,锁定后只能y轴拖动
lockY:            //是否锁定垂直位置,默认false,锁定后只能x轴拖动
onStart:          function () {}, //开始时回调函数
onMove:           function () {}, //拖拽时回调函数
onStop:           function () {}  //停止时回调函数
*/