5拖拽

拖拽的HTML代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>拖拽</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        html, body {
            width: 100%;
            height: 100%;
            background: #e1e1e1;
            overflow: hidden;
        }

        #box {
            visibility: hidden; /*隐藏占位置*/
            position: absolute;
            top: 0;
            left: 0;
            width: 200px;
            height: 200px;
            background: lightblue;
            cursor: move;
        }
    </style>
</head>
<body>
<div id="box"></div>
<!--<script charset="utf-8" type="text/javascript" src="js/utils.min.js"></script>-->
<script charset="utf-8" type="text/javascript" src="js/event.js"></script>
<script type="text/javascript">
    var oBox = document.getElementById("box");

    //JS让盒子处于屏幕正中间位置
    var winW = document.documentElement.clientWidth || document.body.clientWidth, winH = document.documentElement.clientHeight || document.body.clientHeight;//一屏幕的宽高
    var boxW = oBox.offsetWidth, boxH = oBox.offsetHeight;//盒子宽和高

    oBox.style.left = (winW - boxW) / 2 + "px";
    oBox.style.top = (winH - boxH) / 2 + "px";
    oBox.style.visibility = "visible";

    //JS实现拖拽:mouseover mouseout mouseup
    zhufengEvent.on(oBox, "mousedown", down);
    function down(e) {
        this["strX"] = e.clientX;//鼠标起始位置
        this["strY"] = e.clientY;
        this["strL"] = this.style.left;//盒子起始位置(获取行内样式)
        this["strT"] = this.style.top;
        //->
        if (this.setCapture) {
            this.setCapture();//->
            this.setCapture();//->在IE和火狐浏览器中支持这个方法:把鼠标和当前的盒子this绑定在一起了,不管鼠标多快,盒子都可以跟着运动
            zhufengEvent.on(oBox, "mousemove", move);
            zhufengEvent.on(oBox, "mouseup", up);
            return;
        }
        //谷歌:不管鼠标运动多快,始终逃不出document,这样的话我们就把mousemouve/mouseup绑定给document,当方法执行的时候控制盒子运动
        //zhufengEvent.processThis(move,this);//->this就是oBox
        //zhufengEvent.processThis(move,oBox);
        this["MOVE"] = zhufengEvent.processThis(move, this);
        this["UP"] = zhufengEvent.processThis(up, this);
        zhufengEvent.on(document, "mousemove", this["MOVE"]);
        zhufengEvent.on(document, "mouseup", this["UP"]);
    }
    function move(e) {
        var changeX = e.clientX - parseFloat(this["strX"]);//私有变量 鼠标坐标值是一个值 可以加parseFloat
        var changeY = e.clientY - parseFloat(this["strY"]);

        var curL = parseFloat(this["strL"]) + changeX;//120px字符串
        var curT = parseFloat(this["strT"]) + changeY;

        var minL = 0, minT = 0, maxL = winW - boxW, maxT = winH - boxH;
        curL = curL <= minL ? minL : (curL >= maxL ? maxL : curL);
        curT = curT <= minT ? minT : (curT >= maxT ? maxT : curT);
        oBox.style.left = curL + "px";
        oBox.style.top = curT + "px";
    }
    //->
    function up(e) {
        if (this.releaseCapture) {
            this.releaseCapture();//->解绑
            zhufengEvent.off(oBox, "mousemove", move);
            zhufengEvent.off(oBox, "mouseup", up);
            return;
        }
        zhufengEvent.off(document, "mousemove", this["MOVE"]);
        zhufengEvent.off(document, "mouseup", this["UP"]);
    }

</script>
</body>
</html>

引用的event.js代码:

var zhufengEvent = (function () {
    function processThis(callBack, context) {
        var outerArg = Array.prototype.slice.call(arguments, 2);//[100,200]
        return function () {
            var innerArg = Array.prototype.slice.call(arguments, 0); //[e]数组
            callBack.apply(context, outerArg.concat(innerArg));//[100,200,e]
        }
    }

    function bind(curEle, type, fn) {
        //->标准浏览器
        if ("addEventListener" in curEle) {//document.addEventListener
            curEle.addEventListener(type, fn, false);//false:冒泡阶段
            return;
        }
        //->IE6~8
        var tempFn = processThis(fn, curEle);
        tempFn.photo = fn;
        if (!curEle["myBind" + type]) {
            curEle["myBind" + type] = [];
        }
        //->
        var ary = curEle["myBind" + type];
        for (var i = 0; i < ary.length; i++) {
            if (ary[i].photo === fn) {
                return;
            }
        }
        ary.push(tempFn);
        curEle.attachEvent("on" + type, tempFn);
    }

//->unbind:给当前元素的某一个行为移除某一个绑定方法
    function unbind(curEle, type, fn) {
        if ("removeEventListener" in curEle) {//document.addEventListener
            curEle.removeEventListener(type, fn, false);//false:冒泡阶段
            return;
        }
        //->IE6~8
        var ary = curEle["myBind" + type];
        if (ary) {
            for (var i = 0; i < ary.length; i++) {
                var tempFn = ary[i];
                if (tempFn.photo === fn) {
                    curEle.detachEvent("on" + type, tempFn);//->内置的事件池中移除
                    ary.splice(i, 1);//->在自定义属性中也把化妆后的tempFn移除掉
                    break;
                }
            }
        }
    }


    function on(curEle, type, fn) {
        if (!curEle["myEvent" + type]) {
            curEle["myEvent" + type] = [];
        }
        var ary = curEle["myEvent" + type];
        //->如果当前事件池已经存储了这个方法,我们就不需要再存储了
        for (var i = 0; i < ary.length; i++) {
            if (ary[i] === fn) {
                return;
            }
        }
        ary.push(fn);

        bind(curEle, type, fire);
    }

//->off:在自己创建的事件池中移除对应的方法

    function off(curEle, type, fn) {
        var ary = curEle["myEvent" + type];
        if (ary) {
            for (var i = 0; i < ary.length; i++) {
                if (ary[i] === fn) {
                    //ary.splice(i, 1);//->这样每一次移除会把自定义事件池中方法对应的索引进行修改,在执行fire的时候,索引就乱了->"数组塌陷问题"
                    ary[i] = null;
                    return;
                }
            }
        }
    }

    function fire(e) {
        //->统一把e处理兼容了,以后在方法中的e就不需要再处理兼容了
        if (window.event) {
            //IE6~8
            //e = window.event;
            e.target = e.srcElement;
            e.pageX = e.clientX + (document.documentElement.scrollLeft) || document.body.scrollLeft;
            e.pageY = e.clientY + (document.documentElement.scrollTop) || document.body.scrollTop;
            e.preventDefault = function () {
                e.returnValue = false;
            };
            e.stopPropagation = function () {
                e.cancelBubble = true;
            };
        }
        //this->curELe
        var ary = this["myEvent" + e.type];
       // console.log(e.type);
        if (ary) {
            for (var i = 0; i < ary.length; i++) {
                var curFn = ary[i];
                //curFn();//->this->window 应该让每一个方法中的this都变成当前元素this,并且还需要把事件对象传递给对应的方法
                if (typeof curFn === "function") {
                    curFn.call(this, e);
                } else {
                    //->应该是我们在off移除后把这一项的值赋值为null,那此时我们把为null的这一项移除掉
                    ary.splice(i, 1);
                    i--;
                }
            }
        }
    }

    return {
        on: on,
        off: off,
        processThis: processThis
    }
})();

 

posted @ 2016-04-29 19:31  kpengfang  阅读(192)  评论(0编辑  收藏  举报