前端基础进阶(十):面向对象实战之封装拖拽对象

https://segmentfault.com/a/1190000012646488  https://yangbo5207.github.io/wutongluo/

说明:此处只是记录阅读前端基础进阶的理解和总结,如有需要请阅读上面的链接

1.如何让元素动起来

要让元素动起来就要修改元素的top、left 、translate 属性。因为使用top、left会使页面重绘,而translate不会,所以从性能上一般优先使用translate。另外因为translate是transform的一个用法,而transform是css3中的所以需要判断一下浏览器是否支持,不同的浏览器写法大概有几种

['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform']
  //判断当前浏览器支持哪种transform
    function getTransform() {
        var transform = '';
        var divStyle = document.createElement("div").style;
        //不同的浏览器大概支持如下几种transform
        var transArray = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform']

        for (var x in transArray) {
            if (transArray[x] in divStyle)
                return transform = transArray[x];
        }

        return transform;
    }

2.获取元素初始位置

 //获取目标元素样式
    function getStyle(elem, property) {
        //ie 通过currentStyle获取样式,其他浏览器通过getComputedStyle,getComputedStyle是一个方法
        return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property];
    }

  //获取元素的初始位置
    function getTargetPos(elem) {

        var pos = { x: 0, y: 0 };
        var transform = getTransform();
        if (transform ) {
            var transformValue = getStyle(elem,transform);
            if (transformValue == 'none') {
                elem.style[transform] = 'translate(0, 0)';
                return pos;
            } else {
                console.log(transformValue);
                var temp = transformValue.match(/[0-9,\s\.]+/)[0].split(',');
                return pos = {
                    x: parseInt(temp[4].trim()),
                    y: parseInt(temp[5].trim())
                };
            }
        } else {
            if (getStyle(elem, 'position') == 'static') {
                elem.style.position = 'relative';
                return pos;
            } else {
                var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0);
                var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0);
                return pos = {
                    x: x,
                    y: y
                };
            }
        }
    }

设置元素位置

//设置元素位置
        function setTargetPos(elem, pos) {
            var transform = getTransform();
            if (transform != "") {
                elem.style[transform] = "translate(" + pos.x + "px," + pos.y + "px)";
            } else {
                elem.style.left = pos.x + "px";
                elem.style.top = pos.y + "px";
            }
            return elem;
        }

3.事件

拖拽的原理:mousedown记录元素和鼠标的初始位置,添加mousemove、mouseup事件,mousemove事件随着鼠标移动获取鼠标当前位置。移动后的鼠标位置-鼠标的初始位置=移动后的元素位置-元素的初始位置,如果用diss表示移动后的鼠标位置-鼠标的初始位置,那么元素移动后的位置=元素的初始位置+diss。这样在鼠标移动时就可以得到元素的位置。mouseup移除mousemove、mouseup事件和做其他处理

    function start(event) {
        startX = event.pageX; //获取鼠标初始位置
        startY = event.pageY;

        var pos = getTargetPos(oElem);
        sourceX = pos.x;
        sourceY = pos.y;

        document.addEventListener('mousemove', move, false);
        document.addEventListener('mouseup', end, false);
    }

        function move(event) {
            var currentX = event.pageX;
            var currentY = event.pageY;

            var distanceX = currentX - startX;
            var distanceY = currentY - startY;

            setTargetPos(oElem, { x: (sourceX + distanceX).toFixed(), y: (sourceY + distanceY).toFixed() });
        }

        function end(event) {
            document.removeEventListener('mousemove', move);
            document.removeEventListener('mouseup', end);
        }

完整的js代码

 var oElem = document.getElementById("div1"); //document.getElementById("div1")必须在元素加载完成后才能获取到元素,所以这个JavaScript必须放在body后,否则返回null

    var startX = 0;
    var startY = 0;
    var sourceX = 0;
    var sourceY = 0;
    oElem.addEventListener('mousedown', start, false);

    //获取目标元素样式
    function getStyle(elem, property) {
        //ie 通过currentStyle获取样式,其他浏览器通过getComputedStyle,getComputedStyle是一个方法
        return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property];
    }

    //判断当前浏览器支持哪种transform
    function getTransform() {
        var transform = '';
        var divStyle = document.createElement("div").style;
        //不同的浏览器大概支持如下几种transform
        var transArray = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform']

        for (var x in transArray) {
            if (transArray[x] in divStyle)
                return transform = transArray[x];
        }

        return transform;
    }

    //获取元素的初始位置
    function getTargetPos(elem) {

        var pos = { x: 0, y: 0 };
        var transform = getTransform();
        if (transform ) {
            var transformValue = getStyle(elem,transform);
            if (transformValue == 'none') {
                elem.style[transform] = 'translate(0, 0)';
                return pos;
            } else {
                var temp = transformValue.match(/[0-9,\s\.]+/)[0].split(',');
                return pos = {
                    x: parseInt(temp[4].trim()),
                    y: parseInt(temp[5].trim())
                };
            }
        } else {
            if (getStyle(elem, 'position') == 'static') {
                elem.style.position = 'relative';
                return pos;
            } else {
                var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0);
                var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0);
                return pos = {
                    x: x,
                    y: y
                };
            }
        }
    }

        //设置元素位置
        function setTargetPos(elem, pos) {
            var transform = getTransform();
            if (transform != "") {
                elem.style[transform] = "translate(" + pos.x + "px," + pos.y + "px)";
            } else {
                elem.style.left = pos.x + "px";
                elem.style.top = pos.y + "px";
            }
            return elem;
        }

    function start(event) {
        startX = event.pageX; //获取鼠标初始位置
        startY = event.pageY;

        var pos = getTargetPos(oElem);
        sourceX = pos.x;
        sourceY = pos.y;

        document.addEventListener('mousemove', move, false);
        document.addEventListener('mouseup', end, false);
    }

        function move(event) {
            var currentX = event.pageX;
            var currentY = event.pageY;

            var distanceX = currentX - startX;
            var distanceY = currentY - startY;

            setTargetPos(oElem, { x: (sourceX + distanceX).toFixed(), y: (sourceY + distanceY).toFixed() });
        }

        function end(event) {
            document.removeEventListener('mousemove', move);
            document.removeEventListener('mouseup', end);
        }

我们可以把以上代码封装到一个模块里面,使用的时候只要传元素Id就可以了。

;
    (function () {

        var transform = getTransform();

        //构造函数
        function Drag(selector) {
            this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector);
            this.startX = 0;
            this.startY = 0;
            this.sourceX = 0;
            this.sourceY = 0;
            this.init();//初始化
        }

        //原型
        Drag.prototype = {
            constructor: Drag,
            init: function () { this.setDrag(); },
            //获取目标元素样式
            getStyle: function (property) {
                //ie 通过currentStyle获取样式,其他浏览器通过getComputedStyle,getComputedStyle是一个方法
                return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(this.elem, false)[property] : this.elem.currentStyle[property];
            },

            //获取元素的初始位置
            getTargetPos: function () {

                var pos = { x: 0, y: 0 };
                if (transform != "") {
                    var transformValue = this.getStyle(transform);
                    if (transformValue == 'none') {
                        this.elem.style[transform] = 'translate(0, 0)';
                        return pos;
                    } else {
                        var temp = transformValue.match(/[0-9,\s\.]+/)[0].split(',');
                        return pos = {
                            x: parseInt(temp[4].trim()),
                            y: parseInt(temp[5].trim())
                        };
                    }
                } else {
                    if (this.getStyle(this.elem, 'position') == 'static') {
                        this.elem.style.position = 'relative';
                        return pos;
                    } else {
                        var x = parseInt(this.getStyle('left') ? this.getStyle('left') : 0);
                        var y = parseInt(this.getStyle('top') ? this.getStyle('top') : 0);
                        return pos = {
                            x: x,
                            y: y
                        };
                    }
                }
            },

            //设置元素位置
            setTargetPos: function (pos) {
                if (transform != "") {
                    this.elem.style[transform] = "translate(" + pos.x + "px," + pos.y + "px)";
                } else {
                    this.elem.style.left = pos.x + "px";
                    this.elem.style.top = pos.y + "px";
                }
            },

            setDrag: function () {
                var self = this;//因为绑定的方法是独立执行的,this指向并不是Drag对象,所以必须使用闭包
                this.elem.addEventListener('mousedown', start, false);
                function start(event) {
                    self.startX = event.pageX; //获取鼠标初始位置
                    self.startY = event.pageY;

                    var pos = self.getTargetPos();
                    self.sourceX = pos.x;
                    self.sourceY = pos.y;

                    document.addEventListener('mousemove', move, false);
                    document.addEventListener('mouseup', end, false);
                }

                function move(event) {
                    var currentX = event.pageX;
                    var currentY = event.pageY;

                    var distanceX = currentX - self.startX;
                    var distanceY = currentY - self.startY;

                    self.setTargetPos({ x: (self.sourceX + distanceX).toFixed(), y: (self.sourceY + distanceY).toFixed() });
                }

                function end(event) {
                    document.removeEventListener('mousemove', move);
                    document.removeEventListener('mouseup', end);
                }
            }

        }

        // 私有方法,仅仅用来获取transform的兼容写法
        function getTransform() {
            var transform = '',
            divStyle = document.createElement('div').style,
            transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],

            i = 0,
            len = transformArr.length;

            for (; i < len; i++) {
                if (transformArr[i] in divStyle) {
                    return transform = transformArr[i];
                }
            }

            return transform;
        }

        window .Drag=Drag;//对外暴露构造方法
    })();
    new Drag('div1');//拖拽实例

猜你喜欢

转载自www.cnblogs.com/lidaying5/p/9100601.html